C++ 類的建構函式,解構函式,拷貝建構函式,以及隱式例項化物件出現的問題
C++的建構函式和解構函式用於物件的初始化和清理,每個類定義的時候會預設建立三個函式——建構函式,解構函式,拷貝建構函式
1.預設建構函式
建構函式類似於python的__init__方法,在類被例項出一個物件的時候自動呼叫,且只調用一次,預設的建構函式沒有引數且內容為空,可以通過重寫修改預設建構函式,重寫方式為 類名(引數){},建構函式和普通函式一樣,可以過載,所以一個類裡可以有多個構造引數,例項初始化時會根據傳參情況自動識別呼叫。
#include <iostream> using namespace std; #include <string> class PersonTest {string name; public: //注意解構函式必須是公有方法 構造看情況 // 建構函式 類似於init // 多個函式類似於過載,自動識別呼叫 PersonTest() { cout << "預設無引數建構函式的呼叫" << endl; } PersonTest(string name1) { cout << "有參建構函式的呼叫" << endl; name = name1; cout << name << endl; } };int main() { PersonTest p1; string name = "name1"; PersonTest p2(name); PersonTest p3("name2"); system("pause"); return 0; }
在main函式中例項化物件(使用括號法 ),輸入結果如下:
此處在初始化例項物件時,會根據你傳入的引數型別呼叫相應的建構函式;
2. 拷貝建構函式
拷貝建構函式的引數是一個例項化的物件的引用 類名(const 類名 &物件){ }, 該函式的作用在於將傳入的例項物件複製出另一個一樣的物件,兩個物件擁有相同的屬性。 預設的拷貝建構函式是將傳入例項的所有屬性完全複製,重寫拷貝建構函式後,可以複製指定屬性。
//拷貝建構函式 函式值傳遞的時候會自動呼叫拷貝建構函式, 函式返回物件也是呼叫拷貝函式 建立 值傳遞 值返回 PersonTest(const PersonTest & p) { cout << "拷貝建構函式呼叫" << endl; name = p.name; cout << name << endl; }
在例項化物件時,傳入一個已經建立的物件,拷貝建構函式會自動呼叫:
輸出結果為:
拷貝建構函式在三種情況下會呼叫:1利用已有例項複製建立新例項,2 將例項作為函式的形參, 3 將例項作為函式的返回值
3. 解構函式
解構函式類似於python中的__del__函式,在例項物件被銷燬的時候呼叫;預設的解構函式引數為空,內容為空解構函式重寫方式為 ~類名(){} ;注意解構函式不可過載;
// 解構函式 類似於 del方法 不可過載 ~PersonTest() { cout << name << endl; cout << "解構函式呼叫" << endl; }
解構函式必須為公共方法,否則例項銷燬時,系統呼叫會出錯;
4. 建立物件的幾種方法
1.括號法2.顯示法3.隱式轉換法
此處直接上程式碼
int main() { //括號法 PersonTest p1; string name = "name1"; PersonTest p2(name); PersonTest p3("name2"); // 拷貝建構函式 PersonTest p03(p3); //顯示法 PersonTest p4; //無參情況三種方法都是一樣的 PersonTest p5 = PersonTest(name); PersonTest p6 = PersonTest("name2"); PersonTest p7 = PersonTest(p6); //隱式轉換法 PersonTest p8; PersonTest P9 = name; // PersonTest P9 = "name"; 這麼寫會報錯, 因為C++預設一串未定義字串為char[]型 使用cout << typeid("name").name() << endl;檢視變數型別 PersonTest P10 = P9; system("pause"); return 0; }
需要注意的有以下幾點:
1 隱式轉換時,由於建構函式引數型別為string,所以不能使用PersonTest P9 = "name"; 這麼寫會報錯, 因為C++預設一串未定義字串為char[]型 使用cout << typeid("name").name() << endl;檢視變數型別;可以先用 string name = "name"定義,然後用name傳參;
2 顯示法書寫時PersonTest(name); 其實是一個匿名物件,如果不給匿名物件左值,則該條語句執行時會建立一個例項物件,並且在該行執行完畢後銷燬物件;尤為注意不要利用拷貝建構函式初始化匿名物件;如PersonTest(p6), 會報錯重定義; 編譯器會認為是物件p6的宣告;