默認的逐成員初始化和逐位複製有什麼不同?

Default Memberwise Initialization 和 Bitwise copy semantics有什麼區別和聯繫?實在是有點搞不懂。


首先 ,作為一個class X的object instance,如A,然後A的初值是來自於另外一個class X的object instance B。那麼,這個時候內部採用的初始化就是使用了Default Member Initialization來完成。而具體來說,就是把B的Data Member一個一個單獨的拷貝到A上面。而這個時候,如果X裡面還包含有Member Class Object,如class Y,那麼這個時候就不會把B的Member Class Object拷貝到A上,而是遞歸的進行Member Initialization,即再次把Y的Data Member一個一個的拷貝過來,若Y裡面還有Member Class Object Z,那麼依然同理。

而這裡的Member Initialization用的是什麼呢?就是Bitwise Copy and Copy Constructor。而什麼時候使用Bitwise Copy,什麼時候使用 Copy Constructor呢?這要看Class是否展現出來了Bitwise Copy Semantics。一般來說,如果你的class 僅包含了POD(Plain Object Data)這樣的,是展現出了Bitwise Copy Semantics,即編譯器在內部可以一個位元組一個位元組的拷貝(如memcpy)也不會出現問題。然而,當出現了以下幾種情況就是不能使用Bitwise Copy(即簡單來說,使用Bitwise Copy會出錯)

1. Class內部含有一個Member Class Object,如上文的Y,Y內部含有一個Copy Constructor,無論是自定義還是編譯器為其生成的

2. Class繼承的基類還有一個Copy Constructor

3. Class含有virtual function

4. class繼承的基類中,有出現virtual base class的情況

而對於第一二種情況,即需要對Y或者基類的Copy Constructor調用插入在編譯器生成的Copy Constructor中,而對於第三第四種情況則是由於有virtual function的存在,編譯器需要再Copy Constructor中對__vptr進行適當的初始化,以保證指向正確的virtual function table。

大致解釋如此,這裡面其實還可以擴展很多,如什麼時候編譯器會合成Copy Constructor,不過這樣延伸下去就太長了,我這裡就不再贅述了。突發奇想,如果這道題出在C++面試,應該會刷掉很多人吧,比如出題可以出「是否可以使用memcpy來拷貝一個class,並解釋原因」,其實原理是如同上文所述。


class A{

public:

int a;

A operator=(const A obj){......}

}

class B{

public:

A objA;

}

B b1;

B b2=b1;

如果按位複製,A::operator(const A obj) 木有意思了,違背這個賦值運算符重載的初衷了。

樓上講的詳細。


推薦閱讀:

請大神看我對虛函數表和虛基類表的理解對不對?
C++ 有哪些經常用到的設計模式?
如何用C實現C++類裡面的成員?
socket拋出Cant assign requested address,問題所在以及解決方法?
C++序列化json字元串對Unicode有哪些特殊處理?

TAG:面向對象編程 | C |