C++ 默認(rèn)構(gòu)造函數(shù)、拷貝構(gòu)造函數(shù)和移動構(gòu)造函數(shù)的區(qū)別
構(gòu)造函數(shù)三大類型,默認(rèn)構(gòu)造函數(shù)、拷貝構(gòu)造函數(shù)和移動構(gòu)造函數(shù)。
1.默認(rèn)構(gòu)造函數(shù) (Default Constructor)
默認(rèn)構(gòu)造函數(shù)是沒有任何參數(shù)的構(gòu)造函數(shù),或者所有參數(shù)都有默認(rèn)值的構(gòu)造函數(shù)。當(dāng)我們創(chuàng)建一個對象時,若沒有提供初始化參數(shù),程序會調(diào)用默認(rèn)構(gòu)造函數(shù)進(jìn)行初始化。
特點:
默認(rèn)構(gòu)造函數(shù)不需要參數(shù),或者所有參數(shù)都有默認(rèn)值。
如果沒有顯式定義,編譯器會自動生成一個默認(rèn)構(gòu)造函數(shù)(如果沒有其他構(gòu)造函數(shù)的話)。
它用于初始化對象的成員變量,并確保對象處于有效狀態(tài)。
示例:
#include <iostream>
using namespace std;
class MyClass {
public:
MyClass() { // 默認(rèn)構(gòu)造函數(shù)
cout << "Default constructor called!" << endl;
}
};
int main() {
MyClass obj; // 創(chuàng)建對象時調(diào)用默認(rèn)構(gòu)造函數(shù)
return 0;
}
輸出:
Default constructor called!
在這個示例中,我們定義了一個名為 MyClass 的類,并實現(xiàn)了一個默認(rèn)構(gòu)造函數(shù)。當(dāng)我們創(chuàng)建 obj 對象時,程序自動調(diào)用了默認(rèn)構(gòu)造函數(shù)。
2. 拷貝構(gòu)造函數(shù) (Copy Constructor)
拷貝構(gòu)造函數(shù)用于通過現(xiàn)有對象來創(chuàng)建一個新的對象。它通常用于對象的復(fù)制操作,例如將一個對象傳遞給函數(shù)、或者返回一個對象時。
特點:
拷貝構(gòu)造函數(shù)接受一個類的常量引用作為參數(shù)。
它的作用是通過另一個對象的內(nèi)容來初始化新對象。
當(dāng)對象被復(fù)制時,編譯器自動調(diào)用拷貝構(gòu)造函數(shù)。
示例:
#include <iostream>
using namespace std;
class MyClass {
public:
MyClass() { // 默認(rèn)構(gòu)造函數(shù)
cout << "Default constructor called!" << endl;
}
MyClass(const MyClass& other) { // 拷貝構(gòu)造函數(shù)
cout << "Copy constructor called!" << endl;
}
};
int main() {
MyClass obj1; // 調(diào)用默認(rèn)構(gòu)造函數(shù)
MyClass obj2 = obj1; // 調(diào)用拷貝構(gòu)造函數(shù)
return 0;
}
輸出:
Default constructor called!
Copy constructor called!
在這個示例中,我們創(chuàng)建了一個對象 obj1,并將其傳遞給 obj2,這時會調(diào)用拷貝構(gòu)造函數(shù)來創(chuàng)建一個新的對象 obj2,并復(fù)制 obj1 的內(nèi)容。
3. 移動構(gòu)造函數(shù) (Move Constructor)
移動構(gòu)造函數(shù)用于通過轉(zhuǎn)移資源來構(gòu)造對象,避免不必要的資源復(fù)制。在某些情況下,當(dāng)我們傳遞臨時對象或者即將銷毀的對象時,移動構(gòu)造函數(shù)會“竊取”對象的資源,而不是進(jìn)行復(fù)制操作。這種方式大大提高了程序的性能,尤其是在處理大對象或動態(tài)內(nèi)存分配時。
特點:
移動構(gòu)造函數(shù)接受一個右值引用作為參數(shù)。
它會將資源從一個對象轉(zhuǎn)移到另一個對象,而不是復(fù)制資源。
移動構(gòu)造函數(shù)通常用于處理臨時對象或返回對象。
示例:
#include <iostream>
using namespace std;
class MyClass {
public:
MyClass() { // 默認(rèn)構(gòu)造函數(shù)
cout << "Default constructor called!" << endl;
}
MyClass(MyClass&& other) { // 移動構(gòu)造函數(shù)
cout << "Move constructor called!" << endl;
}
};
MyClass createObject() {
MyClass temp;
return temp; // 移動構(gòu)造函數(shù)被調(diào)用
}
int main() {
MyClass obj = createObject(); // 使用移動構(gòu)造函數(shù)
return 0;
}
輸出:
Default constructor called!
Move constructor called!
在這個示例中,createObject 函數(shù)返回一個 MyClass 對象。當(dāng) temp 返回時,程序會調(diào)用移動構(gòu)造函數(shù),因為 temp 是一個臨時對象。通過移動構(gòu)造函數(shù),obj 將直接接管 temp 的資源,而無需復(fù)制資源。
4. 總結(jié)
默認(rèn)構(gòu)造函數(shù)、拷貝構(gòu)造函數(shù)和移動構(gòu)造函數(shù)各自有不同的用途:
默認(rèn)構(gòu)造函數(shù):當(dāng)我們創(chuàng)建一個對象時,它會被調(diào)用,進(jìn)行默認(rèn)初始化。
拷貝構(gòu)造函數(shù):在需要復(fù)制對象時被調(diào)用,如對象傳遞、返回值傳遞等。
移動構(gòu)造函數(shù):當(dāng)傳遞或返回臨時對象時使用,它通過“竊取”資源避免了復(fù)制,提升了性能。