C++構造函數、析構函數不太常見的知識點

關鍵字 構造函數 析構函數
原作者姓名 陳輝東
文章原始出處 [原創]
書籍作者 陳輝東

介紹
本文通過幾個例子來講關於構造函數和析構函數的幾個不太常見知識點。

讀者評分 24 評分次數 7

正文
構造函數和析構函數

衆所周知,所謂構造函數就是一個類的對象(或實例)定義時,由系統自動調用的,用來爲對象分配空間,進行初始化的特殊的成員函數;
而析構函數就是在對象撤消(如出了該對象的作用域)時由系統自動調用,用來回收存儲空間,並做一些善後工作的特殊的成員函數。
本文不再講述構造函數和析構函數的的詳細知識,而是通過幾個例子來講關於構造函數和析構函數的幾個不太常見知識點。
例一、不要改動下面main函數的內容,使程序輸出結果爲:
System initialize...
Hello, my dear friends!
System finish...

下面是該main函數的內容:
// Hello.cpp

#include <iostream.h>
int main(int ac, char *av[])
{
    cout<<"Hello, my dear friends!/n";
}

例二、下面程序的輸出結果是什麼?爲什麼?
#include <iostream.h>
class CHD
{
public:
    CHD()
    {
        cout<<m_age<<endl;
        CHD(20);
    }
    CHD(int age)
    {
        m_age = age;
        show();
    }
    void show()
    {
        cout<<m_age<<endl;
    }
private:
    int m_age;
    
};

int main(int ac, char *av[])
{
    CHD dongdong;
    dongdong.show();
    return 1;
}

如果上面這兩個題目你都覺得很簡單,那我覺得你沒有必要再看下去了。
先來分析第一個題目。不能動main函數體的內容,想一想,正常人都可以想到跟本文所講的構造函數和析構函數有關。可是main函數里根本就沒有和類或類的對象扯上關係呀!這該怎麼入手?
可以這樣想,上面的“System initialize...”應該是類的構造函數裏輸出的內容,而“System finish...”則應該是類的析夠函數裏輸出的內容。可是如何在不讓main出手就能調用到類的構造函數和析構函數呢?
無可爭議的一點是,調用構造函數應該要有該類的對象的存在。雖然在main裏不存在任何對象,可是這個對象還是存在的,因此只能是在main外存在一個對象。因此該對象是一個全局對象。說開了,則寫起來很簡單(下面給出其中一種方法):

#include <iostream.h>

class Chd
{
public:
    Chd(){cout<<"System initialize.../n";};
    ~Chd(){cout<<"System finish.../n";};
}dongdong;

int main(int ac, char *av[])
{
    cout<<"Hello, my dear friends!/n";
    return 1;
}

再來分析第二個題目。
這個題目其實也不難,只要記住一個原則:構造函數和析構函數都是在類的對象(或實例)定義時由系統自動調用的,因此如果人爲的去調用構造函數或析構函數,則系統會自動爲這些構造函數和析構函數指定一個臨時對象。
利用這個原則再去分析第二題,可以知道輸出結果分別是:隨機數(不同系統,不同編譯工具結果不一樣),20,隨機數。
具體的原因,您可以根據以上的原則去分析。

其實,對於非系統調用的構造函數和析構函,可以發現一個規律: 當通過不同渠道調用同一個構造函數,且該構造函數裏邊又調用另一個構造函數,則系統在第二個構造函數裏產生的臨時對象都一樣。

下面給出一個例子,這個例子將其執行的所有構造函數和析構函數的當前對象輸出出來:
/*
*    文件名: CConstruct2
*    功能  : 測試類的構造函數
*    作者  : 陳輝東
*    日期  : 2006.1.3
*    備註  :
*/

#include <iostream.h>

class CHD
{
public:
    CHD(int age)
    {
        cout<<"CHD(int age) initialize... this:"<<this<<endl;
        m_age = age;
    };
    CHD()
    {
        cout<<"CHD() initialize...this:"<<this<<endl;
        CHD(23);    //顯式調用構造函數,則系統會自動創建一個臨時對象
    };
    CHD(int age, int height)
    {
        cout<<"CHD(int age, int height) initialize...this:"<<this<<endl;
        CHD(23);    //顯式調用構造函數,則系統會自動創建一個臨時對象
    };
    ~CHD(){cout<<"finish...this:"<<this<<endl;};
private:
    int m_age;
};

int main(int ac, char *av[])
{
    CHD dongdong;
    CHD::CHD();     //顯式調用構造函數,則系統會自動創建一個臨時對象
    cout<<"======  ========== =========="<<endl;
    CHD dongdong2(10, 160);
    CHD::CHD(20, 170);//顯式調用構造函數,則系統會自動創建一個臨時對象
    cout<<"======  ========== =========="<<endl;
    CHD dongdong1(15);
    CHD::CHD(20);//顯式調用構造函數,則系統會自動創建一個臨時對象

    cout<<"Hello world!/n";
    return 1;
}
/* 輸出結果:(僅供參考)
CHD() initialize...this:0x0012FF70
CHD(int age) initialize... this:0x0012FEFC
finish...this:0x0012FEFC
CHD() initialize...this:0x0012FF64
CHD(int age) initialize... this:0x0012FEFC
finish...this:0x0012FEFC
finish...this:0x0012FF64
======  ========== ==========
CHD(int age, int height) initialize...this:0x0012FF6C
CHD(int age) initialize... this:0x0012FEF4
finish...this:0x0012FEF4
CHD(int age, int height) initialize...this:0x0012FF60
CHD(int age) initialize... this:0x0012FEF4
finish...this:0x0012FEF4
finish...this:0x0012FF60
======  ========== ==========
CHD(int age) initialize... this:0x0012FF68
CHD(int age) initialize... this:0x0012FF5C
finish...this:0x0012FF5C
Hello world!
finish...this:0x0012FF68
finish...this:0x0012FF6C
finish...this:0x0012FF70
Press any key to continue
*/

發佈了33 篇原創文章 · 獲贊 3 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章