[C++] C++疑问?关于copy constructor? [复制链接] 0 0 lc1999 丰衣足食 帖子 879 主题 449 精华 1 可用积分 982 专家积分 0 在线时间 230 小时 注册时间 2003-02-12 最后登录 2012-02-16 问答 好友 博客 消息 论坛徽章: 0 电梯直达 1楼[收藏(0)][报告] 发表于 2005-08-31 05:40:46 | 只看该作者 | 倒序浏览 #include <iostream>; using namespace std; class X { public: X() throw(); X(const X&) throw(); }; X::X() throw() { cout << "default constructor\n"; } X::X(const X&) throw() { cout << "copy constructor\n"; } X userCode(X b) throw() { X c = b; return c; } int main() { X a; cout << "calling userCode()\n"; X d = userCode(a); cout << "back in main()\n"; } 复制代码 以上代码,书上的输出如下: default constructor calling userCode() copy constructor copy constructor copy constructor back in main() 我在windows下用g++,输出如下: default constructor calling userCode() copy constructor copy constructor back in main() 少了一次copy constructor调用。 我发现是这个语句 X d = userCode(a);没有调用copy constructor。 难道是书上错了?Addison.Wesley.Cpp.FAQs.2nd.Edition 谢谢! C++疑问?关于copy constructor? 编译器的优化所致。 如果没有任何优化,拷贝构造函数应该被调用 4 次: 函数实参 a 和虚参 b 结合时 函数内 c 创建并用 b 来初始化时 函数返回时创建临时对象并用 c 来初始化时 对象 d 创建并用函数返回的临时对象初始化时 一般的编译器都可以做到返回值优化(Return Value Optimization, RVO),即直接把返回值建立在函数返回值要初始化或者赋值的对象上(上例中的对象 d)。这个优化的目的是消除函数返回时的临时对象的创建以及拷贝。这样优化之后上面的程序就只有 3 次拷贝了(上表中的 3 被省略,d 变为由 c 直接初始化拷贝),也就是上面书上给出的结果。 在此基础上编译器还可以进行进一步的优化:有名返回值优化(Named Return Value Optimization, NRVO)。NRVO 指的是:如果函数中 return 的对象是一个局部变量且为非 const 或 volatile,编译器可以把这个局部变量(上例中的对象 c)直接建立在函数返回值要初始化或者赋值的对象上(上例中的对象 d)。这样优化之后就只有 2 次对象拷贝操作了(上表中的 3、4 被省略)。 至于这种优化为什么叫“有名”返回值优化,那是因为它优化的对象是函数返回的局部变量,而这个局部变量是有名子的(Named)。与之对应,上面提到的 RVO 是对函数返回临时对象的优化,而这个临时对象是一个无名对象。