1. 程式人生 > 其它 >C++ 類的建構函式,解構函式,拷貝建構函式,以及隱式例項化物件出現的問題

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的宣告;