• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            brent's hut

            C++拷貝構造函數深入分析以及重寫operator =

            ?

            class ?CTestCopyConstruct {
            public :
            ????CTestCopyConstruct()
            {
            ????????TRACE(
            " Enter?CTestCopyConstruct();this?is?%d\n " , this );
            ????????strTest?
            = ? " not?ok " ;
            ????????i?
            = ? 0 ;
            ????}

            ????CTestCopyConstruct(
            const ?CTestCopyConstruct? & src) {
            ????????TRACE(
            " Enter?CTestCopyConstruct(const?CTestCopyConstruct?&src);this?is?%d;src?is?%d\n " , this , & src);
            ????????strTest?
            = ?src.strTest;
            ????????i?
            = ?src.i;
            ????}

            ????CTestCopyConstruct?
            & ?operator? = ( const ?CTestCopyConstruct? & ?src) {
            ????????TRACE(
            " Enter?CTestCopyConstruct?&?operator?=(const?CTestCopyConstruct?&?src);this?is?%d;src?is?%d\n " , this , & src);
            ????????strTest?
            = ?src.strTest;
            ????????i?
            = ?src.i;
            ????????
            return ? * this ;
            ????}

            ????CString?strTest;
            ????
            int ?i;
            }
            ;

            CTestCopyConstruct?GetTest()
            {
            ????CTestCopyConstruct?ret1;
            ????ret1.strTest?
            = ? " ok " ;
            ????ret1.i?
            = ? 0 ;
            ????CTestCopyConstruct?ret2;

            ????
            return ?ret1;
            }


            void ?CTestDlg::OnOK()?
            {
            ????CTestCopyConstruct?var1;
            ????CTestCopyConstruct?var2?
            = ?GetTest();

            ????TRACE(
            " \nresult?1:\n " );
            ????TRACE(
            " var1?is?%d\n " , & var1);
            ????TRACE(
            " var2?is?%d?var2.str?is?%s\n\n " , & var2,var2.strTest);

            ????CTestCopyConstruct?var3?
            = ?var2;
            ????CTestCopyConstruct?var4;
            ????var4?
            = ?var2;

            ????TRACE(
            " \nresult?2:\n " );
            ????TRACE(
            " var3?is?%d?var3.str?is?%s\n " , & var3,var3.strTest);
            ????TRACE(
            " var4?is?%d?var2.str?is?%s\n " , & var4,var4.strTest);
            }



            代碼如上,調試窗口輸出如下:
            Enter CTestCopyConstruct();this is 1242980
            Enter CTestCopyConstruct();this is 1242848
            Enter CTestCopyConstruct();this is 1242840
            Enter CTestCopyConstruct(const CTestCopyConstruct &src);this is 1242972;src is 1242848

            result 1:
            var1 is 1242980
            var2 is 1242972 var2.str is ok

            Enter CTestCopyConstruct(const CTestCopyConstruct &src);this is 1242964;src is 1242972
            Enter CTestCopyConstruct();this is 1242956
            Enter CTestCopyConstruct & operator =(const CTestCopyConstruct & src);this is 1242956;src is 1242972

            result 2:
            var3 is 1242964 var3.str is ok
            var4 is 1242956 var2.str is ok

            分析:
            CTestCopyConstruct var1;\\1
            CTestCopyConstruct var2 = GetTest();\\2
            代碼的執行如下:
            當前堆棧指針(sp) = 1242980
            sp -= 8//在堆棧中為var1分配空間
            在var1上(1242980 - 1242973)調用構造函數
            sp -= 8//在堆棧中為var2分配空間
            sp -= n//保護當前環境
            進入了GetTest函數
            當前sp = 1242848
            sp -= 8//為ret1分配空間
            構建ret1
            sp -= 8//為ret2分配空間
            構建ret2
            ......
            對var2(1242972處的堆棧段)調用拷貝構造函數,以test1(1242848處)為參數
            //析構test1 test2等...
            sp += n//恢復運行環境
            ......

            另:
            operater = () 和默認構造函數不一樣,只重寫=運算符而不提供拷貝構造函數,調用的仍然是默認的構造函數。
            默認構造函數和賦值運算符處理的情況不一樣,一個是在已分配的空間上調用,一個是在已構造的對象上調用。

            默認拷貝構造函數會調用類中各成員的拷貝構造函數。CString 由于提供了拷貝構造函數,所以上面例子中即使去掉拷貝構造函數,var2 仍然會得到正確的值。

            調試的環境是vc6.0 debug 默認選項。編譯沒有優化。

            CTestCopyConstruct( const ?CTestCopyConstruct? & src)
            ????????
            {
            ????????TRACE(
            " Enter?CTestCopyConstruct(const?CTestCopyConstruct?&src);this?is?%d;src?is?%d\n " , this , & src);
            ????????strTest?
            = ?src.strTest;
            ????????i?
            = ?src.i;
            ????}




            CTestCopyConstruct(
            const ?CTestCopyConstruct? & src)
            ????????:strTest?(src.strTest)
            {
            ????????TRACE(
            " Enter?CTestCopyConstruct(const?CTestCopyConstruct?&src);this?is?%d;src?is?%d\n " , this , & src);
            ????????i?
            = ?src.i;
            ????}

            前者先調用了CString::CString()再調用CString::operator =
            后者直接調用了CString::CString(CString & src);


            默認的賦值運算的行為:首先調用父類的賦值運算。
            然后會為自己獨有的各成員尋找賦值運算。如果成員的賦值運算符被重寫,則調用這個重寫的賦值運算符函數,如果這個重寫的運算符函數是private,編譯將無法通過。
            默認的拷貝構造函數的行為:首先調用父類的拷貝構造函數。
            然后為自己獨有的各成員尋找拷貝構造函數。如果這個成員提供拷貝構造函數,則調用之,如果成員的類提供的拷貝構造函數是private,編譯將無法通過。
            (子類完全可以把父類當成自己的一個成員?)


            可以說默認的賦值運算和默認的拷貝構造函數是類最常被用到的兩個函數了...內部卻不是一般的復雜。

            posted on 2006-03-30 10:34 brent 閱讀(1594) 評論(0)  編輯 收藏 引用 所屬分類: C++

            久久精品无码一区二区三区日韩 | 97久久综合精品久久久综合| 无码专区久久综合久中文字幕| 香蕉久久永久视频| 久久无码中文字幕东京热| 99久久夜色精品国产网站| 久久综合亚洲欧美成人| 亚洲精品高清久久| 久久久久亚洲AV成人网人人网站 | 99久久精品免费国产大片| 久久国产精品二国产精品| 久久最新免费视频| 久久无码人妻一区二区三区| 大蕉久久伊人中文字幕| 久久九九兔免费精品6| 久久91精品国产91久久麻豆| 国产欧美久久久精品影院| 99精品久久久久久久婷婷| 亚洲中文字幕无码久久2020| 国产香蕉97碰碰久久人人| 日本久久久久亚洲中字幕| 国产精品免费看久久久香蕉| 久久亚洲精精品中文字幕| 一级做a爰片久久毛片毛片| 欧美综合天天夜夜久久| 久久综合狠狠综合久久综合88 | 久久99久久99小草精品免视看| 亚洲婷婷国产精品电影人久久| 色综合合久久天天综合绕视看| 97精品国产97久久久久久免费| 日本一区精品久久久久影院| 久久久久99精品成人片欧美| 久久综合九色综合网站| 亚洲国产成人精品女人久久久| 欧美久久精品一级c片片| 久久99国产精品久久久| 九九精品99久久久香蕉| 99精品久久精品一区二区| 久久狠狠爱亚洲综合影院| 久久人做人爽一区二区三区 | AV狠狠色丁香婷婷综合久久|