14 More Effective C++—条款20(返回值优化RVO)

针对自定义类型MyClass,我们重载“乘法操作符”。下面将讨论为何返回类型为const MyClass, 并解释什么是RVO。

class MyClass {
	// public function
	// private field
}
const MyClass operator * (const MyClass & lhs, const MyClass& rhs);

1,const修饰返回类型

const针对“自增减运算符”。若不加const修饰,则下面语句相当于生成2个临时对象——obj1+obj2生成的临时对象;(obj1+obj2)结果加1生成的临时对象。这么做会引起对两个对象的混乱。

(obj1+obj2)++

2,返回类型为const MyClass *

const MyClass * operator * (const MyClass& lhs, const MyClass& rhs);

两个数做乘法,如果不修改参与运算的对象,就需要生成一个新对象来储存计算结果。返回一个指针,意味着重载函数内部动态开辟了内存空间,为了防止内存泄露,重载函数外部需要释放内存空间。

内存的申请和释放不在一个作用域,会导致内存泄露问题发生。

3,返回类型为:const MyClass&

const MyClass& operator * (const MyClass& lhs, const MyClass& rhs);

由于函数内部声明的临时变量,在离开函数时被销毁。返回函数内部临时变量的引用,会引起程序的崩溃。如下面代码所示:

int& func() {
	int a;
	return a;
}

4, 返回值优化(RVO-return value optimization)

如下面“片段1”,若先用命名的临时变量temp储存计算结果,然后在返回temp,则函数会再次创建一个匿名的临时变量,这个匿名临时变量在赋值给外部变量result。

// 片段1
MyClass result = obj1 * obj2;
const MyClass operator * (const MyClass& lhs, const MyClass& rhs)
{
	MyClass temp = // do something
	return temp;
}

当时,当我们返回的是一个构造函数,就可以节省temp到临时变量,临时变量到result的开销。编译器经过优化,避免了生成临时变量。如“片段2”所示。这种技术即为“返回值优化技术”

MyClass result = obj1 * obj2;
const MyClass operator * (const MyClass& lhs, const MyClass& rhs)
{
	return MyClass(lhs.num() * rhs.num(),
					lhs.num0() * rhs.num0());
}

通常,编译器倾向消除临时变量,来减少程序运行开销。

猜你喜欢

转载自blog.csdn.net/zhizifengxiang/article/details/84427549