HOME ABOUT CONTACT

C/C++教學: 第三十課 - 類別(Class)的建構(Constructor)和解構(Destructor)

Rain December 26, 2024
Outline

1. 簡介

2. 建構式(Constructor)

3. 解構式(Destructor)

4. 內存洩漏(Memory Leakage)

簡介top

類別的建構(Constructor)和解構(Destrcutor)是讓設計者定義當類別被宣告或釋放時,自動執行對應的操作處理。通常建構式是用來初始化類別中的屬性,或是調用相關初始化的方法,例如GUI的布局等等,而解構式則是釋放已不再使用的記憶體空間。

建構式(Constructor)top

建構式語法類似於函式語法,可以多載,且必須與類別名稱相同,但不須標明回傳類型,我們先來看看下面範例:


class Parent {
public:
    Parent() { //定義第一種建構式,無須任何輸入參數
        m_attr = 0;
        std::cout << "Parent has been declared." << std::endl;
    }
    Parent(int a) { //定義第二種建構式,需給予一個整數型態參數
        m_attr = a; //將參數配置於 m_attr 成員變數
        std::cout << "Parent has been declared and set the attribute: " << a << std::endl;
    }
private:
    int m_attr;
};

void main () {
    Parent p;         //以第一種建構式宣告類別
    Parent p2(100);   //以第二種建構式宣告類別
}
                        

解構式(Destructor)top

解構式語法與建構式語法唯一差異就在有無 "~" 在式子開頭,如下範例:


class Parent {
public:
    Parent() { 
        m_attr = new int(0); //動態配置屬性
        std::cout << "Parent has been declared." << std::endl;
    }
    ~Parent() { //在開頭加上 "~" 即可
        delete m_attr;  //釋放 m_attr 佔用的記憶體空間
        m_attr = nullptr;
        std::cout << "Release the attribte's memory." << std::endl;
    }
private:
    int *m_attr;
};
                        

內存洩漏(Memory Leakage)top

類別的建構式和解構式是在類別生命週期的開頭和結束時,自動地被調用。但要特別注意的是,當類別是被動態配置時,設計者需要自行用 delete 關鍵字將類別刪除,類別才會自動地去調用解構式,我們可以看看下面的範例:


class Parent {
public:
    Parent() { 
        m_attr = new int(0); //動態配置屬性
        std::cout << "Parent has been declared." << std::endl;
    }
    ~Parent() { //在開頭加上 "~" 即可
        delete m_attr;  //釋放 m_attr 佔用的記憶體空間
        m_attr = nullptr;
        std::cout << "Release the attribte's memory." << std::endl;
    }
private:
    int *m_attr;
};

void func() {
    Parent p;
}

void main() {
    func();
}
                        

上例中,我們在 func 函式中以靜態配置的方式宣告了 Parent 類別,函式的開頭會調用到 Parent 的建構式,並且在函式執行結束時,調用了解構式。然而,當我們在函式中用動態配置的方式宣告類別 Parent,但沒有在函式結束之前做 delete 時,儘管函式執行已經結束,解構式仍然不會被調用,如下:


void func() {
    Parent *p = Parent(); //函式只會調用到建構式。
}
                    
void main() {
    func();
}
                        

像這種函式執行完畢,但類別佔用的記憶體空間沒被釋放的情況,我們稱之為內存洩漏(Memory Leakage),嚴重的情況可能會導致整個程式崩壞,因此做好記憶體控管是設計者需要非常注意的事情。

下一篇: 第三十一課 - 樣板(Template)


Last updated:

Related Article List

  1. C/C++教學: 第二十八課 - 類別(Class)的繼承(Inheritance)
  2. C/C++教學: 第二十九課 - 類別(Class)的多形(Polymorphism)
  3. C/C++教學: 第三十一課 - 樣板(Template)