構造函數和析構函數是面向對象編程中非常重要的概念,用於對象初始化和資源清理。在C++中,每個對象都有一個構造函數和一個析構函數,它們在對象的創建和銷毀時分別被調用。
一、構造函數
構造函數在對象創建時被調用,主要用於對象的初始化工作。C++中的構造函數沒有返回值,且函數名與類名相同。
class Student { public: Student(string name, int age) { m_name = name; m_age = age; cout << "構造函數被調用" << endl; } private: string m_name; int m_age; };
上面的代碼定義了一個Student類,其中有一個構造函數,該構造函數接受兩個參數,分別是姓名和年齡。在構造函數中,我們把這兩個參數賦值給m_name和m_age成員變量,然後輸出一句話”構造函數被調用”。
下面是一個示例代碼,創建了一個Student對象,調用構造函數並輸出結果:
Student s("Tom", 18);
執行結果如下:
構造函數被調用
可以看到,我們創建了一個Student對象,並調用了構造函數。
(一)默認構造函數
如果我們沒有為類定義構造函數,編譯器會自動生成一個默認構造函數。默認構造函數沒有參數,什麼也不做。因此,如果我們定義了自己的構造函數,編譯器就不會為我們生成默認構造函數了。
class Student { public: Student() { cout << "構造函數被調用" << endl; } private: string m_name; int m_age; };
上面的代碼定義了一個默認構造函數,沒有參數,只是輸出一句話”構造函數被調用”。
下面是一個示例代碼,創建了一個Student對象,調用默認構造函數並輸出結果:
Student s;
執行結果如下:
構造函數被調用
可以看到,我們創建了一個Student對象,並調用了默認構造函數。
(二)拷貝構造函數
拷貝構造函數在對象拷貝時被調用,主要用於對象的深拷貝。
class Student { public: Student(const Student& s) { m_name = s.m_name; m_age = s.m_age; cout << "拷貝構造函數被調用" << endl; } private: string m_name; int m_age; };
上面的代碼定義了一個拷貝構造函數,接受一個常量引用類型的參數。在函數體中,我們將傳入的Student對象s的姓名和年齡賦值給新創建的對象中的對應成員變量,然後輸出一句話”拷貝構造函數被調用”。
下面是一個示例代碼,創建了一個Student對象s1,然後通過s2 = s1進行對象拷貝並輸出結果:
Student s1("Tom", 18); Student s2 = s1;
執行結果如下:
構造函數被調用 拷貝構造函數被調用
可以看到,我們創建了一個Student對象s1,並調用了構造函數。然後通過s2 = s1進行對象拷貝,並調用了拷貝構造函數。
二、析構函數
析構函數在對象銷毀時被調用,主要用於對象的資源清理工作。C++中的析構函數沒有參數,也沒有返回值,函數名與類名相同,前面加上一個波浪線(~)。
class Student { public: ~Student() { cout << "析構函數被調用" << endl; } private: string m_name; int m_age; };
上面的代碼定義了一個析構函數,沒有參數,只是輸出一句話”析構函數被調用”。
下面是一個示例代碼,創建了一個Student對象s,然後銷毀該對象並輸出結果:
Student s("Tom", 18); // Do something... // ... s.~Student();
執行結果如下:
構造函數被調用 析構函數被調用
可以看到,我們創建了一個Student對象s,並調用了構造函數。然後在執行一些操作之後,手動調用了析構函數銷毀該對象。
(一)析構函數的調用時間
在C++中,析構函數的調用時間是由編譯器決定的。通常來說,在一個對象的作用域結束時,編譯器就會自動調用它的析構函數。當程序執行到函數末尾,或者一個局部對象離開其作用域時,都會調用該對象的析構函數。
void func() { Student s("Tom", 18); // Do something... // ... } // s的作用域結束,析構函數被調用
上面的代碼定義了一個函數func,其中創建了一個Student對象s。在函數結束時,s的作用域結束,編譯器自動調用了它的析構函數。
三、小結
構造函數和析構函數是C++中非常重要的概念,用於對象的初始化和資源的清理。每個類都應該有自己的構造函數和析構函數,以確保對象的正確創建和銷毀。在構造函數中,我們可以對對象的成員變量進行初始化操作,而在析構函數中,則可以進行對象的清理工作。
除此之外,C++中還有很多其他的構造函數和析構函數相關的概念,例如拷貝構造函數、移動構造函數、虛析構函數等等。在實際開發中,我們需要根據具體的需求選擇適當的構造函數和析構函數,來滿足程序的要求。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/271615.html