C++ 返回值优化(N)RVO

(N)RVO: (Named) Return Value Optimization
(具名)返回值优化
声明:本文中的RVO只是表示函数返回对象是非具名的。以及下文中一律以RVO表示具名或非具名返回值优化。

(N)RVO的适用场景

不得不返回类对象的情况下,由于作为返回值的类对象需要调用构造函数、拷贝构造函数、析构函数,带来的开销。这部分开销可以通过返回值优化机制来消除。(默认C++编译器是打开RVO的)

如何使用RVO机制来提高代码效率

通过使用函数的return 位置(或者在函数被调用位置用一个对象来替代)来消除局部临时对象。[^1]

示例代码运行环境

#include <iostream>
using namespace std;

class A 
{ 
	public: 
	A()
	{
	    cout<<this<<" constructor"<<endl; 
	}
	A(const A &other) 
	{
		cout<<this<<" cp contructor from "<<&other<<endl; 
	} 
	A & operator=(const A &other) 
	{
		cout<<this<<" operator = "<<&other<<endl; 
		return *this;
	}
	~A()
	{
		cout<<this<<" destructor"<<endl;
	}
};

示例一

A foo()
{
	return A();
}

int main()
{
	A a = foo();  //返回值优化RVO:利用return的位置;相当于使用a的内存来创建foo临时对象A()
	return 0;
}

运行结果:

0x7ffe25e9ba58 constructor
0x7ffe25e9ba58 destructor

示例二

A foo()
{
	A a;
	return a;
}

int main()
{
	A a = foo();  //返回值优化RVO:利用return的位置;相当于使用a的内存来创建foo临时对象A()
	//foo();   //RVO依然有效
	return 0;
}

运行结果:

0x7ffe15999168 constructor
0x7ffe15999168 destructor

示例三

A foo()
{
	A a;
	return a;  //具名返回
	//return A();  //不具名返回
}

int main()
{
	A a;
	a = foo();  //error
	return 0;
}

运行结果:(具名返回和不具名返回的运行结果一样)

0x7ffeede2a268 constructor
0x7ffeede2a260 constructor
0x7ffeede2a268 operator = 0x7ffeede2a260

signal: illegal instruction (core dumped)

其中,0x7ffeede2a260应该是foo()返回的临时对象。

对于示例三的结果,我的理解是,通过赋值运算符接收函数返回的临时类对象时,没有返回值优化。即

接收栈对象的方式不同,会影响优化。

拓展

  • 如果foo()是一段短小的、被频繁调用的函数,可以将其定义为inline函数来避免函数调用开销。
inline A foo()
{
    ...
}

参考:

[1] https://blog.csdn.net/qianqin_2014/article/details/51333388

发布了15 篇原创文章 · 获赞 0 · 访问量 962

猜你喜欢

转载自blog.csdn.net/zimovv/article/details/98195977