C++构造函数、拷贝构造函数、赋值运算符漫谈(三)——NRV

来源:互联网 发布:多张图像拼接算法综述 编辑:程序博客网 时间:2024/05/17 08:35

首先看下面一段程序:

转载请尊重原创、保留相关链接本文来自多宝平台http://www.mbodb.com

点击(此处)折叠或打开

  1. class X
  2. {
  3. public:
  4. X()
  5. {
  6. cout<<"X()"<<endl;
  7. };
  8. X(int v):val(v)
  9. {
  10. cout<<"X(int)"<<endl;
  11. }
  12. X(const X& x)
  13. {
  14. cout<<"X(const X& x)"<<endl;
  15. }
  16. X& operator=(const X&)
  17. {
  18. cout<<"="<<endl;
  19. return *this;
  20. }
  21. ~X()
  22. {cout<<"destructor"<<endl;}
  23. void memfun()
  24. {
  25.   cout<<"memfun"<<endl;
  26. }
  27. private:
  28. int val;
  29. };
  30. int _tmain(int argc, _TCHAR* argv[])
  31. {
  32.    X x0(1024);
  33. X x1=X(1024);
  34. X x2=(X)1024;
  35. }


 

    以上两个运行结果截图分别来自VSg++

    看到这个输出,相信不少人和我一样有疑惑:为什么没有调用拷贝构造函数?在回答这个疑问之前,我们先解决另外一个疑问——使用“=”创建的对象就一定要调用拷贝构造函数吗?

     从运行结果来看是否定的,在创建x1,x2的时候,我们的预想是编译器先创建一个临时对象,多宝在使用临时对象作为拷贝构造函数的参数创建新对象。其实这里编译器采用了一种优化,叫做Named Return Value(NRV)。

Named Return value 优化:

nrv优化的本质是优化掉拷贝构造函数,去掉它不是生成它。当然了,因为为了优化掉它,前提就是它存在,也就是欲先去之,必先有之,这个也就是nrv优化需要有拷贝构造函数存在的原因。 nrv优化会带来副作用,目前也不是正式标准,倒是那个对象模型上举的应用例子看看比较好。极端情况下,不用它的确造成很大的性能损失,知道这个情况就可以了。  

为什么必须定义了拷贝构造函数才能进行nrv优化?首先它是lippmaninside c++ object mode里说的。那个预先取之,必先有之的说法只是我的思考。查阅资料,实际上这个可能仅仅只是cfont开启NRV优化的一个开关。 

The C++ standard allows the elision of the copy constructor (even if this results in different program behavior), which has a side effect of enabling the compiler to treat both objects as one。也就是我说的副作用,c++标准允许这个副作用的出现,也就是它允许进行NRV优化,但不是必须。 

0 0