問題
拷貝構造和賦值重載有什么區別
我的回答
拷貝構造函數和賦值運算符重載是C++中兩個看似相似但用途和行為有明顯區別的特性。
拷貝構造函數是用來創建一個新對象作為已存在對象的副本。它的形式是ClassName(const?ClassName& other),在以下情況會被調用:
- 用一個對象初始化另一個新對象時
- 函數按值傳遞對象參數時
- 函數返回對象時(如果沒有RVO/NRVO優化)
例如:
MyClass obj1;
MyClass obj2 = obj1; // 調用拷貝構造函數
MyClass obj3(obj1); // 也是調用拷貝構造函數
賦值運算符重載則是用于已經存在的兩個對象之間的賦值操作。它的形式通常是ClassName& operator=(const ClassName&?other),當使用賦值符號=給一個已存在的對象賦值時被調用。
例如:
MyClass obj1, obj2;
obj2 = obj1; // 調用賦值運算符重載
兩者的關鍵區別在于:
對象生命周期:拷貝構造函數是在創建新對象時調用的,而賦值運算符是在兩個已存在的對象之間賦值時調用的。
資源管理:賦值運算符通常需要先釋放當前對象已經擁有的資源,然后再復制新資源;而拷貝構造函數只需要分配和復制資源,因為新對象還沒有任何資源。
自我賦值檢查:賦值運算符需要處理自我賦值的情況(如obj =?obj),而拷貝構造函數不需要,因為新對象不可能是自己的副本。
返回值:賦值運算符通常返回對象的引用(*this)以支持連續賦值,而拷貝構造函數沒有返回值。
調用時機:編譯器會在多種隱式情況下調用拷貝構造函數,而賦值運算符只在顯式使用=且左側對象已存在時調用。