類和物件_物件的初始化和清理(中)
阿新 • • 發佈:2021-08-07
建構函式呼叫規則
預設情況下,C++編譯器至少給一個類新增3個函式
- 預設建構函式(無參,函式體為空)
- 預設解構函式(無參,函式體為空
- 預設拷貝建構函式,對屬性進行值拷貝
建構函式呼叫的規則如下:
- 如果使用者定義 有參建構函式,C++不再提供預設建構函式,但是會提供預設拷貝構造
- 如果使用者定義 拷貝建構函式,C++不再提供其他建構函式
深拷貝與淺拷貝
深拷貝與淺拷貝是面試經典問題,也是常見的一個坑
淺拷貝:簡單的賦值拷貝操作 (編譯器提供的拷貝建構函式)
深拷貝:在堆區重新申請空間,進行拷貝操作
淺拷貝帶來的問題:堆區記憶體重複釋放
淺拷貝的問題利用深拷貝來解決(自己寫拷貝建構函式)
#include <iostream> using namespace std; class Person { public: Person() { cout << "預設建構函式呼叫" << endl; } Person(int age, int height) { m_Age = age; m_Height = new int(height); //返回的是地址 //堆區開闢的資料手動開闢手動釋放//height需要在解構函式中釋放 cout << "有參建構函式呼叫" << endl; } Person(const Person &p) { m_Age = p.m_Age; //m_Height = p.m_Height; 這是編譯器預設的拷貝操作 //深拷貝操作 m_Height = new int(*p.m_Height); cout << "拷貝建構函式呼叫" << endl; } ~Person() { //將堆區開闢的資料做釋放操作 if (m_Height != NULL) { delete m_Height; m_Height = NULL; //防止野指標出現 做置空操作 } cout << "解構函式呼叫" << endl; } int m_Age; int * m_Height; //身高 用指標是因為要開闢到堆區 }; void test01() { Person p1(18, 160); Person p2(p1); } int main() { test01(); }
總結:如果屬性有在堆區開闢的,一定要自己提供拷貝建構函式,防止淺拷貝帶來的問題
初始化列表
作用:
C++提供了初始化列表,用來初始化屬性
語法:建構函式(): 屬性1(值1), 屬性2(值2) ... {}
#include <iostream> using namespace std; class Person { public: //傳統初始化操作 // Person(int a, int b, int c) { // m_A = a; // m_B = b; // m_C = c; // } //初始化列表 Person(int a, int b, int c):m_A(a), m_B(b), m_C(c) { } int m_A; int m_B; int m_C; }; int main() { Person p(10, 20, 30); cout << "m_A = " << p.m_A << endl; cout << "m_B = " << p.m_B << endl; cout << "m_C = " << p.m_C << endl; }