C++對象模型(二):The Semantics of Copy Constructors(拷貝構造函數之編譯背後的行為)
本文是 Inside The C++ Object Model's Chapter 2 的部分讀書筆記。
有三種情況,需要拷貝構造函數:
1)object直接為另外一個object的初始值
2)object作為函數以值傳遞的參數
3) object以函數返回值形式返回
如果class沒有提供一個explicit copy constructor時,編譯器會以default memberwise initialization,也就是把每一個內建的或者派生的data member的值,從某個object直接拷貝到另外一個object上,對於member class object,以遞歸的方式施行memberwise initialization。
編譯器並不會生成trivial的copy constructor,除非是bitwise copy semantics,以下四種情況就是非bitwise copy semantics:
1)class的某個member object聲明有一個copy constructor時,這個copy constructor不會是被設計者聲明的,或者是被編譯器合成的
2)class繼承自的base class含有copy constructor時
3)class含有virtual functions
4)class的base class是virtual時
編譯器需要合成copy constructor,並且調用member object或者base class的copy constructor。
對於virtual function或者virtual inheritance,編譯器需要為每一個object設計好vptr以便在runtime獲取到正確的virtual function table。因為vptr處理不好有可能發生對象的sliced,導致出現blow up。
總結:
如果class是bitwise copy semantics,那麼編譯器不會合成copy constructor,隻是按照default memberwise initialization copy source object到destination object。否則,編譯器將合成copy constructor,以調用member object或者base class的copy constructor或者使得vptr設置好,使得在runtime可以使virtual base class或者base class可以正確訪問virtual functions。
注意,本文隻是說明編譯器在copy constructor上為我們做了什麼,並不是編譯器合成的copy constructor就是安全可用的。這裏需要和deep copy(深拷貝)/shallow copy(淺拷貝)加以區別。和編譯器是否為我們合成default constructor一樣,它隻是完成自己的職責,並不會為non class member object and non-static members 初始化。 如果需要deep copy,設計者必須explicit declare copy constructor。否則即使編譯器合成了,也會使得程序出現undefined behaviors。
最後更新:2017-04-03 12:53:35