一つのテーマから思いついたC++コンパイラの最適化問題

4223 ワード

この2,3日1つの問題を見て、見たところ簡単で、しかし使う知識は本当に少なくなくて、原題は以下の通りです:
#include "stdafx.h"

class Base
{
public:
    Base(){}
    virtual ~Base(){}
    Base(const Base &other);            //    ,    
private:
    Base &operator=(const Base &other);
} ;

int _tmain(int argc, _TCHAR* argv[])
{
    const Base &b = Base() ;        //            ?             ,          !   

    return 0;
}

最初に考えたのは、コンパイラの最適化です.
コンパイラは最適化されたと推測される:const Base&b=Base();このように書くと、意味によっては:
1.Baseのコンストラクタを呼び出す
2.Baseの付与関数b=一時オブジェクトを呼び出すが、コンパイラはこのような2つのステップを踏む必要はないと考え、Baseのコンストラクション関数を直接呼び出す...
その後、大侠Aの指導を経て、問題点を指摘した.
Base b=aの場合、bはまだ構造されていないので、まずbを構造し、次に値を付ける必要があります.c++コンパイラの設計者は、最適化しないことができますか?だからすべてのc++でこの行為を規定して、すなわちBase b=aはBase b(a)で、これもc++文法のsweetです.
うん....ではしばらくconst Base&b=Base();コンパイラによってBaseb(Base()になってしまうと、やはりデフォルトのコンストラクタとコピーコンストラクタが呼び出されるでしょう.プログラムが間違っていないのに!!!
キーパーソンBが現れた:
    ,const Base &b = Base() ;                    ,          ,                 。
   ISO/IEC 14882:2003(E)  
8.5.3 References
 4 5  
— Otherwise, the reference shall be to a non-volatile const type (i.e., cv1 shall be const). 
[Example:
double& rd2 = 2.0; // error: not an lvalue and reference not const
int i = 2;
double& rd3 = i; // error: type mismatch and reference not const
—end example]
— If the initializer expression is an rvalue, with T2 a class type, and “cv1 T1” is reference-compatible with “cv2 T2,” the reference is bound in one of the following ways (the choice is implementation-defined):
— The reference is bound to the object represented by the rvalue (see 3.10) or to a sub-object within that object.
— A temporary of type “cv1 T2” [sic] is created, and a constructor is called to copy the entire rvalue object into the temporary. The reference is bound to the temporary or to a sub-object within the temporary.93)

こんなに英語が山積みになっているのを見てまたぼんやり...心を静めてよく読みました.
肝心なのはこの話にある.
— If the initializer expression is an rvalue, with T2 a class type, and “cv1 T1” is reference-compatible with “cv2 T2,” the reference is bound in one of the following ways (the choice is implementation-defined)://               ,               ,       ,               (    ):
— The reference is bound to the object represented by the rvalue (see 3.10) or to a sub-object within that object.//          
— A temporary of type “cv1 T2” [sic] is created, and a constructor is called to copy the entire rvalue object into the temporary. The reference is bound to the temporary or to a sub-object within the temporary.//       ,                    ,           。

明らかに私がテストしたVC、GCCはすべて第1の方法を選んで直接引用を右の値にバインドします...~
参照に関するいくつかの説明は、ネットワークから抜粋しています.http://blog.csdn.net/wfwd/article/details/763551
/*
(1)&         ,       。

(2)              。

(3)     ,           。

(4)       ,             ,           ,                   。

ra=1;     a=1;

(5)      ,          ,                   ,
           ,            ,             。
 :      ,          。&ra &a  。

(6)         。                   ,             。
*/
       ,        :

  (1)           。      Effective C++[1] Item 31。                   ,            "   "   ,         。

  (2)        new        。      Effective C++[1] Item 31。                ,       (      new       ),         。  ,                    ,             ,            ( new  )     ,  memory leak。

  (3)          ,    const。        Effective C++[1] Item 30。                   (business rule)      ,                     ,                     。                   (   ),                       。

  (4)           :

      << >>,               ,  :cout << "hello" << endl;                                。         :                 。           ,      (  )         ,    ,     <<              !       。                <<   。  ,              。         ,                 ,     C++               。      =。            ,        ,  :x = j = 10;  (x=10)=100;                ,         。                   。