| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 632 人关注过本帖
标题:關於構造函數與析構函數的測試用例
只看楼主 加入收藏
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
结帖率:100%
收藏
 问题点数:0 回复次数:4 
關於構造函數與析構函數的測試用例
以下是一個測試何時調用構造函數和析構函數的程序,注釋見於代碼內。

程序代码:
#include <iostream>
#include <string>

const std::string Wait_Message("Press any key to continue...");

// 複數類定義
class Complex
{
    public:

        Complex(double x, double y) : _x(x), _y(y)
        {
            ++Create_Count;
            std::cout << "Create[" << Create_Count << "]: (" << _x << ", " << _y << ")" << std::endl;
        }

        ~Complex()
        {
            ++Destroy_Count;
            std::cout << "Destroy[" << Destroy_Count << "]:(" << _x << ", " << _y << ")" << std::endl;
        }

        friend Complex operator+(const Complex& a, const Complex& b)
        {
            // 此處形參是引用,不會創建對象,故看不到a、b的構造函數
            return Complex(a._x + b._x, a._y + b._y);
        }

    private:
        
        double _x;        // 實部
        double _y;        // 虛部

        static int Create_Count;        // 構造計數器
        static int Destroy_Count;        // 析構計數器
};

int Complex::Create_Count = 0;
int Complex::Destroy_Count = 0;

void Pause(const std::string msg)
{
    std::cout << std::endl << msg;
    std::cin.get();
}

void Test(Complex& x)
{
    // 形參是引用,無需複製,故x不會調用構造函數,此處x為調用處a+b所得的臨時對象

    Complex a(11, 12);        // 創建一個對象,將會調用構造函數,此對象在函數結束時銷毀,看到析構函數
    Complex b(a + x);        // 用a+x創建一個對象,將會調用構造函數,此對象在函數結束時銷毀,看到析構函數
}

int main(void)
{
    Complex a(1, 2);        // 創建一個對象,將會調用構造函數,此對象在程序結束後銷毀,看不到析構過程
    Complex b(3, 4);        // 創建一個對象,將會調用構造函數,此對象在程序結束後銷毀,看不到析構過程
    Test(a + b);            // 將a、b運算之後所得到的臨時對象以引用方式傳入一個子函數

    Pause(Wait_Message);
    return 0;
}


根據注釋描述,即知何以出現5次構造卻僅有3次析構。

運行結果:
图片附件: 游客没有浏览图片的权限,请 登录注册


[ 本帖最后由 TonyDeng 于 2015-10-6 11:27 编辑 ]
2015-10-04 22:15
wmf2014
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:216
帖 子:2039
专家分:11273
注 册:2014-12-6
收藏
得分:0 
学习ing

能编个毛线衣吗?
2015-10-06 09:04
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
構造函數和析構函數,與其說那是方法,不如說是事件。方法是需要或可以主動調用的,但事件是要在條件滿足時才會觸發的。構造函數祗在對象創建時觸發,析構函數在對象銷毀時觸發。對象的創建和銷毀,不是程序員可以完全控制的,這與C的free()一樣,發出free()之後,堆中的數據並不一定會馬上被回收(那是操作系統在認為適當時候做的),在C++中,你也同樣無法要什麼時候銷毀對象就可以銷毀對象。

析構函數裏面做什麼動作,必須仔細斟酌,不要亂來。在對象仍然存在的時候,你去主動執行析構函數中的動作,可能會破壞對象後續動作所需要的環境,典型如資源句柄,你提前關閉了句柄,到對象真的被執行銷毀動作的時候,操作系統還會調用析構函數,此時句柄已經失效,那麼同樣的動作就會失敗。

如上面測試示例,程序員可以預料函數test()在結束後銷毀哪些對象,也觀察得到,但卻無法觀察到函數main()結束後銷毀其內部對象的結果,因為銷毀動作在main()的return發出之後。不管是程序的開頭還是結尾,都有大量的前導和收尾工作,程序也不真的從main()開始和結束,大量的暗動作是你看不到的。

[ 本帖最后由 TonyDeng 于 2015-10-6 14:00 编辑 ]

授人以渔,不授人以鱼。
2015-10-06 13:48
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
C++的引用比C的指針好用,其中一個優勢就是引用傳參省略了複製過程,它很簡單地給對象一個別名了事,哪怕對象體積再龐大也沒問題,而對C來說,當對象體積龐大的時候要使用指針傳參,然而指針本身也是一個數據,在參數傳遞中仍然是値複製,要複製指針的値給形參,指針形參是本身佔棧空間的間接尋訪,而引用形參是不佔棧空間的直接尋訪,效率不同。

授人以渔,不授人以鱼。
2015-10-06 13:53
h1187647735
Rank: 2
来 自:湖北huang'g
等 级:论坛游民
帖 子:26
专家分:17
注 册:2014-11-19
收藏
得分:0 

努力学习   天天向上
2015-10-07 16:58
快速回复:關於構造函數與析構函數的測試用例
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.028407 second(s), 11 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved