1. 程式人生 > 其它 >類和物件_物件的初始化和清理(中)

類和物件_物件的初始化和清理(中)

建構函式呼叫規則

預設情況下,C++編譯器至少給一個類新增3個函式

  1. 預設建構函式(無參,函式體為空)
  2. 預設解構函式(無參,函式體為空
  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;
}