<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    C++對象的構造、賦值和析構

    Posted on 2006-11-25 16:08 iceboundrock 閱讀(646) 評論(1)  編輯  收藏 所屬分類: 算法與數據結構學習

    C++ C#/java 有很多區別,其中最大的區別當數對內存的管理。

    C++ 中,類的使用者決定了類的實例內存會如何分配,分配在堆上還是棧上。我們先看一段例子程序:

    ?

    #include "stdio.h"

    ?

    class Demo{

    public :

    ??? int i;

    ??? char* objName;

    ??? Demo(){

    ??????? objName = "Default object.";

    ??????? printf("%s, objName = %s\r\n", "Enter Demo default ctor. method.", objName);

    ???????

    ??????? i = 1000;

    ??? }

    ?

    ??? Demo(int ival, char* name){

    ??????? printf("%s,i = %d, objName = %s\r\n", "Enter Demo(int ival) ctor method", ival, name);

    ??????? i = ival;

    ??????? objName = name;

    ??? }

    ?

    ??? Demo(const Demo& d){

    ??????? printf("%s\r\n", "Enter Demo copy ctor method.");

    ??????? i = d.i;

    ??????? objName = "copied d";

    ??? }

    ?

    ??? ~Demo(){

    ??????? printf("%s, i = %d, objName = %s\r\n", "Enter Demo dector. method" , i, objName);

    ??? }

    };

    ?

    Demo& testMethod0(){

    ??? printf("%s\r\n", "Enter testMethod0.");

    ??? Demo d(0, "d in testMethod0");

    ??? printf("%s\r\n", "Exit testMethod0.");

    ??? return d;

    }

    ?

    Demo testMethod1(){

    ??? printf("%s\r\n", "Enter testMethod1.");

    ??? Demo d(1, "d in testMethod1");

    ??? printf("%s\r\n", "Exit testMethod1.");

    ??? return d;

    }

    ?

    Demo* testMethod2(){

    ??? printf("%s\r\n", "Enter testMethod2.");

    ??? Demo *d = new Demo(2, "d in testMethod2");

    ??? printf("%s\r\n", "Exit testMethod2.");

    ??? return d;

    }

    ?

    int main(int argc, _TCHAR* argv[])

    {

    ??? Demo d;

    ??? d = testMethod1();

    ?

    ??? Demo& d1 = testMethod0();

    ?

    ??? Demo d2(999, "d1");

    ?

    ??? Demo* d3 = testMethod2();

    ?

    ??? printf("d.i = %d\r\n", d.i);

    ??? printf("d1.i = %d\r\n", d1.i);

    ??? printf("d2.i = %d\r\n", d2.i);

    ??? printf("d3.i = %d\r\n", d3->i);

    ?

    ??? delete d3;

    ??? return 0;

    }

    ?

    Output

    Enter Demo default ctor. method., objName = Default object.

    Enter testMethod1.

    Enter Demo(int ival) ctor method,i = 1, objName = d in testMethod1

    Exit testMethod1.

    Enter Demo copy ctor method.

    Enter Demo dector. method, i = 1, objName = d in testMethod1

    Enter Demo dector. method, i = 1, objName = copied d

    Enter testMethod0.

    Enter Demo(int ival) ctor method,i = 0, objName = d in testMethod0

    Exit testMethod0.

    Enter Demo dector. method, i = 0, objName = d in testMethod0

    Enter Demo(int ival) ctor method,i = 999, objName = d1

    Enter testMethod2

    Enter Demo(int ival) ctor method,i = 2, objName = d in testMethod2

    Exit testMethod2.

    d.i = 1

    d1.i = -2

    d2.i = 999

    d3.i = 2

    Enter Demo dector. method, i = 2, objName = d in testMethod2

    Enter Demo dector. method, i = 999, objName = d1

    Enter Demo dector. method, i = 1, objName = copied d

    ?

    C# 不同,在 C++ 中,對象聲明的時候就已經執行了構造函數,比如上面例子的 main 函數中的第一行, Demo d ,從屏幕上的輸出來看,這個時候 Demo class 的默認構造函數會被調用。

    接下來的一行代碼調用,引出了很有趣的情況,當然也隱藏著不小的問題。這行代碼造成了一次構造函數調用,一次拷貝構造函數調用和兩次析構函數調用。讓我們來具體分析一下:第一次調用構造函數很容易理解,因為在 testMethod1 中我們聲明了 Demo d(0) ,退出 testMethod1 ,函數的返回值要賦值給變量 d2 ,這個時候, d2 被拷貝構造函數重新構造了一次。接著 testMethod1 中構造的局部變量被析構,然后,居然拷貝構造函數構造的對象也被析構?等等,看完所有輸出,我們發現, objName = copied d 的對象被析構兩次,而 objName = Default obj 的對象被構造出之后沒有被析構,這里隱藏了很嚴重的問題,有可能導致內存泄漏、句柄不能被正確關閉等等。另外,拷貝構造函數的執行可能導致潛在的效率問題,考慮一個包含巨大矩陣的對象, copy 這個對象會怎么樣?

    ?

    接下來的一行代碼, testMethod0 返回一個對象的引用,當然不會導致拷貝構造函數被調用,但是,這樣也是有問題的,在函數中聲明的局部變量在函數執行完成的時候會被析構,那么直接返回局部變量就可能會出現問題。 testMethod0 退出以后,他內部的 Demo 對象就會自動析構,外面對它的引用當然也無法指向正確的對象了,所以后面程序打印 d.i 的時候,輸出了一個莫名其妙的 -2

    ?

    效率最好的方法當數返回指針了,它不會導致對象復制,如果使用得當,也不會導致內存泄漏或者句柄泄漏。 testMethod2 演示了這種情況,當然,你需要手工刪除在 testMethod2 中創建的對象。

    ?

    ?

    Feedback

    # re: C++對象的構造、賦值和析構  回復  更多評論   

    2006-11-28 09:50 by iceboundrock
    補充一點關于數組的內容,
    如果在C++中聲明一個對象的數組,不像C#,數組中默認的元素都是null,C++的數組中可以容納多少元素就會在聲明數組的時候執行多少次構造函數將實際函數構造出來。

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     

    posts - 10, comments - 15, trackbacks - 0, articles - 0

    Copyright © iceboundrock

    主站蜘蛛池模板: 亚洲卡一卡2卡三卡4麻豆| 中文字幕亚洲综合久久菠萝蜜| 亚洲免费在线视频| 99热在线日韩精品免费| 国产亚洲美女精品久久久| 国产成人无码免费看片软件| 免费在线观看中文字幕| 最近高清国语中文在线观看免费| 亚洲精品自拍视频| 无码国产精品一区二区免费虚拟VR| 日本免费一二区在线电影| 亚洲av中文无码乱人伦在线r▽ | 久久亚洲精品成人综合| 免费人成在线观看视频高潮| 久久精品国产亚洲一区二区| 久久精品一本到99热免费| 成人亚洲综合天堂| 亚洲冬月枫中文字幕在线看| 成年人在线免费看视频| 国产亚洲精彩视频| 亚洲人成影院在线无码按摩店| 亚洲国产成人精品无码区花野真一| 国产一级淫片a免费播放口| 久久久久亚洲av无码专区喷水| 无码国产精品久久一区免费| 亚洲成a人无码亚洲成www牛牛| 亚洲高清国产拍精品青青草原| 免费91麻豆精品国产自产在线观看| 亚洲精品91在线| 日韩精品视频免费观看| 国产黄片不卡免费| 亚洲成人免费网址| 少妇太爽了在线观看免费视频 | 亚洲av无码成h人动漫无遮挡| 国产大片91精品免费观看不卡| 免费v片视频在线观看视频| a级毛片免费完整视频| 亚洲人妖女同在线播放| 亚洲片国产一区一级在线观看| 国产精品亚洲色婷婷99久久精品| 亚洲啪啪综合AV一区|