我们知道,函数运行结束后,函数内部的局部变量就会消失,当函数返回的对象的时候,会产生一个临时对象,这样会消耗很多的计算资源,写一段代码进行测试。
#includeusing namespace std; class MyBuff { public: MyBuff() { cout << "MyBuff()" << endl; } MyBuff(const MyBuff& b) = delete; MyBuff& operator=(const MyBuff& b) = delete; ~MyBuff() { cout << "~MyBuff()" << endl; } MyBuff(MyBuff&& b) noexcept { cout << "move construct" << endl; } MyBuff& operator=(MyBuff&& b) noexcept { cout << "move assign " << endl; return *this; } }; class bbuffer { public: bbuffer() {} void show() { cout << "sh bbuffer" << endl; } ~bbuffer() {} }; MyBuff GetBuff() { MyBuff res; cout << &res << endl; bbuffer b_; b_.show(); return res; } int main() { MyBuff b = GetBuff(); cout << &b << endl; }
执行结果如下:
MyBuff() 0x7ff7bb322258 show bbuffer 0x7ff7bb322258 ~MyBuff()
是不是感觉和理解的不对,这时候好像并没有产生一个临时的对象,我们发现b和临时对象res的地址是一样的,并且res的析构是在整个程序结束的时候执行的,难道编译器进行了优化。
之后百度发现有一种优化叫做返回值优化机制,传送门,编译时候加入参数 -fno-elide-constructors优化。
从新执行代码结果如下
MyBuff() 0x7ff7b2e2a200 show bbuffer move construct ~MyBuff() move construct ~MyBuff() 0x7ff7b2e2a258 ~MyBuff()
这时候
MyBuff()是在GetBuff()函数内部进行构造。
返回的时候生成临时变量,(函数的返回值为右值)触发一次移动构造,之后析构res.
之后临时变量用来构造main中的c,之后析构
函数执行完成,c被析构。
为什么没有调用移动赋值构造,传送门



