大家好,请看以下代码:
#include<iostream> using namespace std; class Point { public: Point(int xx,int yy); Point(const Point &p); Point& operator = (const Point &p); int getx(){return x;}; int gety(){return y;}; ~Point() { } private: int x; int y; }; Point::Point(int xx,int yy) { x=xx; y=yy; } Point::Point(const Point &p) { x=p.x; y=p.y; cout<<"copy is ok\n"; } Point& Point::operator= (const Point &p) { x=p.x; y=p.y; cout<<"= is ok\n"; } Point func2() { Point a12(3,4); return a12; } int main(int argc,char **argv) { Point p = func2(); return 0; }
问一下两个问题:
1.func2函数中a12作为返回值返回给func2,这里为什么没有生成临时的中间变量Point对象?
2.func2的返回结果不是返回给p吗?为什么没有调用拷贝构造函数吗?为什么结果没有输出””copy is ok”?
解决方案
15
原因是返回值优化,把临时变量,和复制全都优化掉了
你关闭优化看看啥情况
你关闭优化看看啥情况
15
函数在返回的时候,使用的 汇编代码是 ret 。
此时不管函数需要返回什么,都约定是 AX 寄存器中的值。
哪怕是 void 函数,也是一样的。
但是假设 返回值的大小大于 DX:AX 的所能包含的。
那么编译器会把函数的返回值当作最后一个参数。
在呼叫函数的时候,会在堆栈上创建一个临时的返回值。
然后当作参数压栈。
此时不管函数需要返回什么,都约定是 AX 寄存器中的值。
哪怕是 void 函数,也是一样的。
但是假设 返回值的大小大于 DX:AX 的所能包含的。
那么编译器会把函数的返回值当作最后一个参数。
在呼叫函数的时候,会在堆栈上创建一个临时的返回值。
然后当作参数压栈。
15
vs2013 返回 copy is ok
可能是编译优化的问题.
可能是编译优化的问题.
15
在return a12的时候,C++编译器,首先将创建一个匿名对象,然后用a12对象去初始化这个匿名对象,这个时候就会调用匿名对象的拷贝构造函数(俗称return副本),接着a12析构,func2()函数返回
在p接收到func2()函数返回的匿名对象之后(=号操作符之后),匿名对象析构
一点浅析.希望有高手指点.
在p接收到func2()函数返回的匿名对象之后(=号操作符之后),匿名对象析构
一点浅析.希望有高手指点.
15
你用的什么IDE.或是编译器
20
返回值优化(Return Value Optimization,简称RVO),是这么一种优化机制:当函数需要返回一个对象的时候,假如本人创建一个临时对象用户返回,那么这个临时对象会消 耗一个构造函数(Constructor)的调用、一个复制构造函数的调用(Copy Constructor)以及一个析构函数(Destructor)的调用的代价。而假如稍微做一点优化,就可以将成本降低到一个构造函数的代价,假如是用的VS,Debug模式(没有优化)和Release模式就不一样(在GCC下测试的时候可能编译器本人进行了RVO优化,看不到两种代码的区别)
5
1 编译器优化,RVO机制
2 仍然是RVO机制部分
2 仍然是RVO机制部分
10
参看:http://blog.csdn.net/yao_zou/article/details/50759301
另参看:《深度探索C++对象模型》
另参看:《深度探索C++对象模型》
5
你怎么知道没有生成临时变量呢?你析构函数又没有输出什么东西,你在析构函数里面打印下信息就知道了,其实有个对象被析构了,所以它还是生成了临时变量的。你本人搞错了