命名的返回值优化(Named Return Value optimization (NRVO))

命名的返回值优化:

  针对返回一个局部的变量的优化,可以直接用返回的结果对象直接替代局部变量,从而减少了一个复制拷贝,从而提高效率。

比如 一个函数如下:

X bar()
{
X xx;
// .. 处理xx
return xx;
}

而在编译器看来则是如下的代码:

  


// 此处的_result是一个在调用该函数时产生的一个临时对象
// , 然后将该对象传入,用以接受结果
void bar(X & __result)
{

X xx;

// 调用xx的构造函数
xx.X::X();

// .. 处理xx

// 拷贝构造函数
_result.X::X(xx);
return;
}

上面是没有采用NRVO优化的,优化后的代码是:


void bar(X & __result)
{
// 拷贝构造函数,直接用__result替换掉局部变量
// 从而提高了效率
__result.X::X();

// .... 对xx的处理,变成了对__result的处理

return;
}

在gcc下写了一个测试:


#include <iostream>
using namespace std;

class Base
{
public:

Base()
{
cout << "构造函数" << endl;
}

~Base()
{
cout << "析构函数" << endl;
}
};

Base test()
{
Base a;
return a;
}

int main()
{
test();
return 0;
}

结果为:

其实结果应该有两个"构造函数"与"析构函数"的输出,因为在test函数中,有一个局部变量的生成,还有一个返回值,应该生成一个对象,然后返回,但是在结果中,我们只看到了一对,所以是采用了NRVO优化的。在《深度探索C++对象模型》这本书中说,需要是copy
constructor(拷贝构造函数)才说激活NRVO,但是在这个程序中没有生成copy constructor却也行,所以表示怀疑。

时间: 2024-10-13 10:07:42

命名的返回值优化(Named Return Value optimization (NRVO))的相关文章

More Effective C++----(20)协助完成返回值优化

Item M20:协助完成返回值优化 一个返回对象的函数很难有较高的效率,因为传值返回会导致调用对象内的构造和析构函数(参见条款M19),这种调用是不能避免的.问题很简单:一个函数要么为了保证正确的行为而返回对象要么就不这么做.如果它返回了对象,就没有办法摆脱被返回的对象.就说到这. 考虑rational(有理数)类的成员函数operator*:(返回类型为const是为了防止连续对操作符的操作,一是返回的对象是一个临时对象,多个操作是在其临时对象上的操作,二是不符合内置类型的要求) class

C++返回值优化

返回值优化(Return Value Optimization,简称RVO)是一种编译器优化机制:当函数需要返回一个对象的时候,如果自己创建一个临时对象用于返回,那么这个临时对象会消耗一个构造函数(Constructor)的调用.一个复制构造函数的调用(Copy Constructor)以及一个析构函数(Destructor)的调用的代价. 经过返回值优化,就可以将成本降低到一个构造函数的代价.这样就省去了一次拷贝构造函数的调用和依次析构函数的调用. 例子如下: class MyString {

转:C++中临时对象及返回值优化

http://www.cnblogs.com/xkfz007/articles/2506022.html 什么是临时对象? C++真正的临时对象是不可见的匿名对象,不会出现在你的源码中,但是程序在运行时确实生成了这样的对象. 通常出现在以下两种情况: (1)为了使函数调用成功而进行隐式类型转换的时候. 传递某对象给一个函数,而其类型与函数的形参类型不同时,如果可以通过隐式转化的话可以使函数调用成功,那么此时会通过构造函数生成一个临时对象,当函数返回时临时对象即自动销毁.如下例: //计算字符ch

参数返回值及NRV优化(named return value optimization)

C++11中的移动构造函数又把NRV优化翻出来了,都是采用临时中间值优化,两者不能共存. 参数传递如何实现? [实现模型1]引入临时对象,使用拷贝构造函数初始化.然后利用bitwise copy将其拷贝到x0的位置.比如: void foo( X x0 ); X xx; foo( xx ); 改写成 X __temp0; __temp0.X::X ( xx ); foo( __temp0 );还有一件事需要做,修改foo的声明,可以避免bit-wise copy的那一步. void foo( X

[转] C++中临时对象及返回值优化

http://www.cnblogs.com/xkfz007/articles/2506022.html 什么是临时对象? C++真正的临时对象是不可见的匿名对象,不会出现在你的源码中,但是程序在运行时确实生成了这样的对象. 通常出现在以下两种情况: (1)为了使函数调用成功而进行隐式类型转换的时候. 传递某对象给一个函数,而其类型与函数的形参类型不同时,如果可以通过隐式转化的话可以使函数调用成功,那么此时会通过构造函数生成一个临时对象,当函数返回时临时对象即自动销毁.如下例: //计算字符ch

C++返回值优化RVO

返回值优化,是一种属于编译器的技术,它通过转换源代码和对象的创建来加快源代码的执行速度.RVO = return value optimization. 测试平台:STM32F103VG + Keil 5.15 背景:我们有个MacAddress::ToArray byte* MacAddress::ToArray() const { return (byte*)&Value; } 因为封装需要,打算返回字节数组类ByteArray的对象,于是有 ByteArray MacAddress::To

python之路——函数返回值return

return关键字 没有返回值 返回一个值 返回多个值 1.没有返回值 ----不写return的情况下,会默认返回一个None:下面的函数,就没有写return,这就是没有返回值的一种情况. #函数定义 def mylen(): """计算s1的长度""" s1 = "hello world" length = 0 for i in s1: length = length+1 print(length) #函数调用 str_

C++返回值为对象时复制构造函数不执行怎么破

先说点背景知识,调用复制构造函数的三种情况: 1.当用类一个对象去初始化另一个对象时. 2.如果函数形参是类对象. 3.如果函数返回值是类对象,函数执行完成返回调用时. 在辅导学生上机时,有同学第3点提出异议.有教材上的例题为证: #include <iostream> using namespace std; class Point //Point 类的定义 { public: Point(int xx=0, int yy=0) { x = xx; //构造函数,内联 y = yy; } P

Python全栈__函数的初识、函数的返回值、函数的参数

1.函数的初识 def关键字 空格 函数名(与变量名命名规则相同):英文冒号 函数体 执行函数:函数名+() 函数是以功能为导向的. def login(): pass def register(): pass 1 def my_len(): 2 l1 = [1, 2, 3, 1, 6, 9, 10] 3 count = 0 4 for i in l1: 5 count += 1 6 my_len() 2.函数的返回值 return: 1.函数中遇到 return 结束函数,下面代码不执行. d