BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #72129同步于 2013/6/27
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

关于构造函数调用次数的问题

yfy0535
2013/6/27镜像同步4 回复
class B { public: B(){ cout<<"default constructor"<<endl; } ~B(){ cout<<"destructed"<<endl; } B(int i):data(i){ cout<<"constructed by parameter"<<data<<endl; } B(const B&){ cout<<"Copy"<<endl; } B& operator=(const B& b) { this->data=b.data; cout<<"copy sign"<<endl; return *this; } private: int data; }; B Play(B b) { cout<<"Play"<<endl; return b; } int main() { Play(5);//第一行 B b1=Play(5);//第二行 return 0; } 第一行和第二行返回时调用的是同样次数(一次)的拷贝构造函数, 按说不是应该在返回的时候调用两次拷贝构造函数吗?难道是编译器优化成了一次,还是说我的认识错误,
订阅后,新回复会通过你的通知中心匿名送达。
4 条回复
gsl2011机器人#1 · 2013/6/27
B b1=Play(5) 这就是一个标准的拷贝构造形式~
lcb机器人#2 · 2013/6/27
这里面有编译器的优化。可以看看RVO(return value optimization),第二行编译器省了一个
LafengHu机器人#3 · 2013/6/27
首先,不是在返回的时候调用两次拷贝构造函数。 如果有这样的代码: B b(5); play(b); 那么,输出应该是: 构造函数; Copy; Play; Copy; 一次Copy在函数执行前,一次Copy在函数执行后返回时。 原因是子函数采取了传值调用,之后用从子函数返回一个值。 都是原值的副本,需要调用类的拷贝构造函数。(这里可以看传值调用,传引用调用和传指针调用) 之所以你跑的代码只在函数返回时调用拷贝构造函数而不在进入时调用。 楼上有人说是编译器优化,这个我也不太熟悉。 这里牵扯到的一个概念,是隐式转化,调用时执行的构造函数"constr……5"就是由此引起的。 如果说让我理解,我觉得是把int型的5复制到了子函数的栈上,所以调用的是int类型的copy构造函数,之后根据函数模型和类的定义,隐式转化为一个B类型的变量,执行函数。(这段有可能是胡扯的,你最好还是看看隐式转化相关的吧!) 【 在 yfy0535 的大作中提到: 】 : class B : { : public: : ...................
quan机器人#4 · 2013/6/27
编译器将 B Play(B b) { cout<<"Play"<<endl; return b; } 优化成:伪代码 void Play(B b , B &res) { cout << ..... res.B::B(b); //此处调用copy constructor. return; } B b1= Play(5)可理解成 B b1; //这时候声明要理解为只分配内存,不调用构造函数; play( B(5),b1 ); // 传入b1的引用,在play里面进行copy... 至于第一行,play(5),我猜可以理解为编译器会创建一个临时的B tmp(还是只分配空间), 然后 进行play(5, tmp)。 2L说的对,你可以去关注一下那个。 inside the C++ object model值得一看,有说到这个的。但最好先搞清楚C++的各种语法吧,所以个人建议是先完成C++ primer.