C++通过引用来传递和返回类对象

类是 C++ 语言面向对象编程的载体,我们也可以将类视为一种特殊的数据类型。在 C++ 语言中,由类声明的对象,和其它类型声明的变量一样,同样可以通过传值、引用和指针的方式作为函数的参数或函数返回值。

除非迫不得已,最好不要采用传值的方式传递和返回对象,因为采用传值的方式传递和返回对象的过程中需要经历对象间的拷贝操作,一定程度上会降低程序运行的效率,从而使得待处理数据量增大,增加内存的使用,而采用引用或指针的方式则不会有这样的问题。实际上,因为引用表达更加简练直观,因此也较少使用指针来传递对象或作为函数返回值。

【例 1】对象引用举例:
class book
{
    ... ...
};

book Alice;
book &Alice_reference = Alice;
对象的引用和普通的变量引用基本语法是一样的。如例 1 所示,先定义了 book 类,之后定义了 book 类对象 Alice,最后一句定义了 Alice_reference 是 Alice 对象的引用。

【例 2】通过引用的方式来传递和返回对象:
#include<iostream>
using namespace std;

class book
{
public:
    void setprice(double a);
    double getprice();
    void settitle(char* a);
    char * gettitle();
private:
    double price;
    char * title;
};

void book::setprice(double a)
{
    price = a;
}

double book::getprice()
{
    return price;
}

void book::settitle(char* a)
{
    title = a;
}

char * book::gettitle()
{
    return title;
}

void display(book & b)
{
    cout<<"The price of "<<b.gettitle()<<" is $"<<b.getprice()<<endl;
}

book & init(char *t, double p)
{
    static book b;
    b.settitle(t);
    b.setprice(p);
    return b;
}

int main()
{
    book Alice;
    Alice.settitle("Alice in Wonderland");
    Alice.setprice(29.9);
    display(Alice);
    book Harry;
    Harry = init("Harry Potter", 49.9);
    display(Harry);
    return 0;
}
在本例中,我们继续沿用之前定义的 book 类,只不过类中新增添了title这个成员变量,为了能够操控 title 变量,我们与之相对应地新增了两个 public 属性的成员函数 settitle() 和 gettitle(),这两个函数都是在类内部声明,类外部定义的。

之所以将成员函数都放到类外定义主要是为了使得类定义看起来简洁明了,类中定义了哪些成员变量,哪些成员函数,一目了然。

除了定义 book 类以外,我们还定义了两个函数,一个是 display() 函数,其参数为 book 类对象的引用;另一个函数是 init() 函数,其返回值是 book 类对象的引用。这两个函数前者是为了打印图书的书名及价格信息,后者则是为了初始化对象。

我们来看一下主函数,首先用 book 类定义了一个 Alice 对象,并且调用 settitle() 和 setprice() 函数分别设置 Alice 对象的相关成员变量,之后调用顶层函数 display(),打印 Alice 对象的相关信息。

在此之后,我们又定义了一个 Harry 对象,该对象直接调用顶层函数 init() 来进行初始化。经过 init() 函数内部初始化后,将对象的引用返回给 Harry 对象,最终同样调用 display() 函数打印 Harry 对象的相关信息。

程序最终运行结果如下:

The price of Alice in Wonderland is $29.9
The price of Harry Potter is $49.9

这个例子向我们展示了通过引用的方式来传递和返回对象,需要注意的是函数返回一个对象的引用的时候,最好该对象不是局部变量或临时变量(如果是局部变量或临时变量,一旦该函数运行结束,该局部变量或临时变量很有可能会被系统销毁),如本例中 init() 函数在定义 b 对象时前面加上了一个 static 关键字,将 b 对象声明为一个静态对象。