X xx = x;void foo(X x); foo(xx);X foo() { X xx; return xx; }若類未聲明複製構造函數,編譯器**不會**自動生成一個函數,而是在需要時進行「概念上的」逐成員複製:
例如 String 類含 char* str; int len;,複製時僅複製指針值與長度,**不**深度複製字符串內容(淺拷貝)。若含 String 類型成員,則遞歸調用其複製構造。
類滿足「位逐次拷貝」語意,當且僅當:
此時編譯器**不合成**複製構造函數,直接對內存區塊進行 memcpy 式複製,極高效。
合成複製構造函數會**顯式設置**新對象的 vptr 指向正確的虛函數表,而非直接複製來源對象的 vptr。這對於基類對象用派生類對象初始化(切割 slicing)至關重要:基類副本的 vptr 必須指向基類 vtable,否則虛函數調用會崩潰。
虛基類在派生類中位置不固定(運行期確定)。位逐次複製會破壞虛基類指針/偏移。合成複製構造函數會插入代碼重新初始化虛基類指針,確保後續訪問正確。
若類滿足位逐次拷貝語意,編譯器會優化掉複製構造函數調用,直接內聯內存複製。若用戶提供了複製構造函數(即使語意相同),編譯器**必須**調用它(可能有副作用),無法優化。這是 C++ 性能與語意的權衡。
memcpy。