編譯器在下面幾種情況下會給程式設計師沒有提供拷貝建構函式的類自動生成拷貝建構函式
1.類中有虛函式
當這個類中有虛函式的時候,意味著這個類的物件中一定包含了指向其虛函式表的指標
試想,如果講該類的派生類的物件作為該類的初始化物件,即
b繼承a
class a
private:
int m_a;
public:
virtual void showval();
}void a::showval()
printf("%d", m_a);
}class b
private:
int m_b;
public:
void showval();
}void b::showval()
printf("%d", m_a);
}int main()
b b;
a a = b; // 此處應該呼叫a類的拷貝建構函式
}在main中a a = b;時,如果程式設計師沒有提供拷貝建構函式,而編譯器也不提供,那麼就會按照簡單的位拷貝進行拷貝,即將b物件中a子物件的部分按位拷貝給a物件,這是就會出現乙個問題,b物件中包含的vbpt指向的時b類的虛函式表,而不是a類的。如果這樣直接位拷貝的時候,當呼叫a.showval函式,執行的時b類的showval,就不正確了。
因此,這裡編譯器判斷a類在拷貝構造的時候並沒有顯現出位拷貝的特徵,不能只是用位拷貝,因此編譯器會為a類合成乙個拷貝建構函式,如下
a::a(a& a)
this->vptr = a類的虛函式表的位址;
}即編譯器必須查收生成乙個拷貝建構函式用來重新設定vptr的值。
在這裡插一句,如果程式設計師提供了拷貝建構函式的話,編譯器會不會做什麼動作?
答案時當然會,因為程式設計師提供的拷貝建構函式中也不會去做重新設定vptr的動作,這裡當然會由編譯器代勞了,編譯器會在程式設計師提供的拷貝建構函式中
為何編譯器無法自動生成拷貝函式
c 編譯器一般會為使用者自定義型別生成預設拷貝函式。它的行為是逐位複製。逐位複製的意思不是memcpy,而是逐個變數進行複製。很多書有教導如何禁用掉編譯器的拷貝函式 自己宣告乙個private的拷貝函式。不過有些時候我們沒有故意禁用拷貝函式,卻發現編譯錯誤 提示沒有相應拷貝函式。這是為什麼呢?一般發...
編譯器自動生成預設建構函式的情況
在程式設計師沒有為類定義預設建構函式的情況下,c 編譯器在某些情況下會自動生成預設建構函式。1.類中包含的其他有預設建構函式的類的物件 例如 class a private int data public a a a this data 10 class b private a m a int m ...
何時編譯器會自動生成預設建構函式
問題 對c 初學者來說存在乙個誤區,如果類沒有定義任何建構函式,編譯器會自動生成預設的建構函式。注意 這種說法是錯誤的。正確的說法 惟有預設建構函式 被需要 的時候編譯器才會合成預設建構函式。那什麼情況下是 被需要 的時候?以下有四種情況編譯器會自動合成預設建構函式 情況1含有類物件資料成員,該類物...