有关返回对象的说明(C++)

当成员函数或独立的函数返回对象时,有几种返回方式可供选择。可以返回指向对象的引用、指向对象的const引用或const对象。

返回指向const对象的引用:

使用const引用的常见原因是旨在提高效率,但对于何时可以采用这种方式存在一些限制。如果函数返回传递给它的对象,可以通过返回引用来提高其效率。例如:

Vector force1(50, 60);
Vector force2(10, 70);
Vector max;
max = Max(force1, force2);

Vector Max(const Vector &v1, const Vector &v2) {
	if (v1.magval() > v2.magval())	return v1;
	else return v2;
}

const Vector & Max(const Vector &v1, const Vector &v2) {
	if (v1.magval() > v2.magval())	return v1;
	else return v2;
}

这两种实现都是可行的,首先,返回对象将调用复制构造函数,而返回引用不会。因此,第二个版本所做的工作更少,效率更高。其次,引用指向的对象应该在调用函数执行时存在。在这个例子中,引用指向force1或force2,它们都是在调用函数中定义的,因此满足这种条件。第三,v1和v2都被声明为const引用,因此返回类型必须是const,这样才匹配。

返回指向非const对象的引用:

两种常见的返回非const对象情形是,重载赋值运算符以及重载与cout一起使用的<<运算符。前者这样做旨在提高效率,而后者必须这样做。
operator=()的返回值用于连续赋值:

String s1("Good stuff");
String s2, s3;
s1 = s2 = s3;

在上述代码中,s2.operator=()的返回值被赋给s3。为此,返回String对象或String对象的引用都是可行的,但与Vector示例中一样,通过使用引用,可避免函数调用String的复制构造函数来创建一个新的String对象。在这个例子中,返回类型不是const,因为方法operator=()返回一个指向s2的引用,可以对其进行修改。

operator<<()的返回值用于串接输出:

String s1("Good stuff");
cout << s1 << " is coming!";

在上述代码中,operator<<(cout,s1)的返回值称为一个用于显示字符串“is coming!”的对象。返回类型必须是ostream &,而不能仅仅是ostream。如果使用返回ostream,将要求调用ostream类的复制构造函数,而ostream没有公有的复制构造函数。

返回对象:

如果被返回的对象是被调用的函数中的局部变量,则不应按引用方式返回它,因为在被调用函数执行完毕时,局部对象将调用其析构函数。因此,当控制权回到调用函数时,引用指向的对象将不再存在。在这种情况下,应返回对象而不是引用。通常,被重载的算数运算符属于这一类:

Vector force1(50, 60);
Vector force2(10, 70);
Vector net;
net = force1 + force2;

返回的不是force1也不是force2,force1和force2在这个过程中保持不变。因此返回值不能是指向在调用函数中已经存在的对象的引用。相反,计算得到的两个矢量的和被存储在一个新的临时对象中,该函数也不应返回指向该临时对象的引用,而应该返回实际的Vector对象,而不是引用:

Vector Vector::operator+(const Vector &b) const {
	return Vector(x + b.x, y + b.y);
}

返回const对象:

前面的Vector::operator+()定义有一个奇异的属性,它旨在让你能够以下面这样的方式使用它:

net = force1 + force2;

然而,这种定义也允许您这样使用它:

force1 + force2 = net;
cout << (force1 + force2 = net).magval() << endl;

这种代码之所以可行,是因为复制构造函数将创建一个临时对象来表示返回值,因此,在前面的代码中,表达式force1 + force2的结果为一个临时对象,然后net被赋给该临时对象。使用完临时对象后,将把它丢弃。
如果担心这种行为可能引发的误用和滥用,可以将返回类型声明为const Vector。

总之,如果方法或函数要返回局部对象,则应返回对象,而不是指向对象的引用。在这种情况下,将使用复制构造函数来生成返回的对象。如果方法或函数要返回一个没有公有复制构造函数的类的对象,它必须返回一个指向这种对象的引用。最后,有些方法和函数可以返回对象,也可以返回指向对象的引用,在这种情况下,应首选引用,因为其效率更高。

声明:以上整理自个人理解和Stephen Prata 著的《C++ Primer Plus》

猜你喜欢

转载自blog.csdn.net/MoooLi/article/details/82806841