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

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

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

    so true

    心懷未來,開創(chuàng)未來!
    隨筆 - 160, 文章 - 0, 評論 - 40, 引用 - 0
    數(shù)據(jù)加載中……

    構(gòu)造函數(shù)與const的關(guān)系

    B b;(1)
    A a=b;(2)
    A a=B();(3)
    A a(b);(4)
    如果(2)能執(zhí)行成功的話,那么需要滿足什么?(2)到底與(4)有什么區(qū)別?(4)能執(zhí)行成功的條件與(2)有什么區(qū)別?
    回答完上述問題, 我順便還能回答一個問題: A(A& a)與A(const A& a)有什么區(qū)別?
    下面就來回答這個問題:
    首先來分析(2)是如何執(zhí)行的,分為以下步驟:
    1. b能轉(zhuǎn)化為一個A的臨時對象;(轉(zhuǎn)化的方法可以是B自身包含一個到A的強制類型轉(zhuǎn)換操作符或者A有一個未指定explicit的參數(shù)為B或者B&或者const B&的構(gòu)造函數(shù)
    2. 調(diào)用A的拷貝構(gòu)造函數(shù), 而且必須是A(const A& a), 如果沒有const是不行的, 至于原因我一會兒再說
    再說說(3)執(zhí)行的步驟與條件:
    1. B的這個臨時對象能轉(zhuǎn)化為一個A的臨時對象; (轉(zhuǎn)化的方法可以是B自身包含一個到A的強制類型轉(zhuǎn)換操作符或者A有一個未指定explicit的參數(shù)必須為B或者const B&的構(gòu)造函數(shù)
    2. 調(diào)用A的拷貝構(gòu)造函數(shù), 而且必須是A(const A& a), 如果沒有const是不行的, 至于原因我一會兒再說
    最后說說(4)執(zhí)行的條件:
    A有參數(shù)為B或者B&或者const B&的構(gòu)造函數(shù);
    或者是: B自身支持強制類型轉(zhuǎn)化為某種類型, 該類型能恰好為A的某一個構(gòu)造函數(shù)的參數(shù).

    按照我上面的分析, 對于(2)和(3)如果B自身不提供轉(zhuǎn)化機制的話, 那么豈不是要調(diào)用A的構(gòu)造函數(shù)兩次了, 其實最后只調(diào)用一次就可以了, 也就是步驟2里調(diào)用A的拷貝構(gòu)造函數(shù)不會被調(diào)用, 但這只是編譯器作了優(yōu)化, 省掉了一次, 并不代表只執(zhí)行步驟1, 不信的話你把A拷貝構(gòu)造函數(shù)里的const去掉試試看, 要是能編譯過去才怪.

    那說到根兒上, 加不加const修飾到底有啥區(qū)別呢?
    其實這才是關(guān)鍵所在, 理解了這個也就知道本質(zhì)原因了, 下面我就來說說這個const:
    首先要讓大家知道A(const A&)和A(A&)是兩個函數(shù)吧?也就是構(gòu)造函數(shù)的重載, 對于重載的函數(shù)參數(shù)類型或個數(shù)至少得有點不同, 這里我告訴你參數(shù)類型加不加const是完全不同的兩種參數(shù)類型.
    知道了上面的概念, 再引用一段話:(出自http://www.xmsc.com.cn/InfoView/Article_122425.html)
    說說左值和右值以及臨時對象的問題。也許你會說左值應(yīng)該就是能夠改變的變量,右值當(dāng)然就是不能改變的變量嘍!對嗎?對了一點點,實際上左值是能夠被引用的變量,說的通俗點就是有名字的變量,你一定想到了些什么,對了,臨時變量就沒有名字,即使有你也不會知道,因為它不是由你創(chuàng)建的,編譯器會在內(nèi)部辨別它,但你并不知道,因此臨時變量不是左值,而是右值。你也許還會問,那const變量是不是左值呢?根據(jù)定義,它有名字,當(dāng)然就是左值了。因此左值并非一定“ 可被修改”。但是左值和右值與參數(shù)有什么關(guān)系嗎?我要告訴你的是:有,而且相當(dāng)密切,因為標(biāo)準(zhǔn)c++規(guī)定:若傳遞給類型為引用的形參的實參是右值的話必須保證形參為const引用。
    其實上面這段話最關(guān)鍵的地方在于指出了左值能被引用右值不能被引用, 臨時變量以及沒有顯示名字的變量都是右值, 因此在(2)或(3)中生成的A的臨時變量必定是右值, 而A的構(gòu)造函數(shù)必須為引用類型, 因此按照"若傳遞給類型為引用的形參的實參是右值的話必須保證形參為const引用"這個斷言, A的拷貝構(gòu)造函數(shù)里包含const也就是必須的了.

    所以大家要消除一個固有的概念: 拷貝構(gòu)造函數(shù)就得A(const A&)這么寫, 完全錯誤, 其實A(A&)有些情況下是必須有的, 沒有都不行, 比如auto_ptr, 因為它在調(diào)用拷貝構(gòu)造函數(shù)時, 需要把自己當(dāng)前維護的那根指針銷毀掉(即設(shè)為NULL)同時把這根指針交給另一個auto_ptr保管.
    下面的代碼是我自己實驗的一個小例子:
    using namespace std;

    template <typename T>
    class A
    {
    public:
        A(){}

        A(A& a)
        {
            cout<<"A(A& a)"<<endl;
        }

        template <typename T2>
        A(const A<T2>& a)
        {
            cout<<typeid(T).name()<<endl;
            cout<<typeid(T2).name()<<endl;
            cout<<"A(const A<T2>&a)"<<endl;
        }
    };

    int main(int argc, char* argv[])
    {
        A<int> a_int;
        A<string> a=(a_int);
        return 0;
    }

    輸出結(jié)果是:
    Ss
    i
    A(A<T2>&a)
    Ss
    Ss
    A(A<T2>&a)
    如果把A的兩個拷貝構(gòu)造函數(shù)都加上const,或者把模板拷貝構(gòu)造函數(shù)的那個const移到非模板拷貝構(gòu)造函數(shù)上, 結(jié)果都會為:
    Ss
    i
    A(A<T2>&a)
    上述代碼是在linux的gcc3.4下通過的, 我相信大家應(yīng)該可以分析出原因來, 不過對于模板類我還是得羅唆幾句, 首先大家應(yīng)該清楚A<int>和A<string>是完全不同的兩個類型, 就像int和string一樣風(fēng)馬牛不相及, 只不過它們公用了一些模板代碼而已, 因此你把A<int>和A<string>看作兩個不同的類型來分析就應(yīng)該能分析透徹了.

    在http://www.xmsc.com.cn/InfoView/Article_122425.html一文中還講解了auto_ptr中auto_ptr_ref的作用, 說到這里,讓我真的很恨auto_ptr源碼中的注釋啊,因為它的注釋有錯誤,一直誤導(dǎo)了我, 現(xiàn)在才體會到“錯誤的注釋還不如沒有注釋”的真諦了。錯誤出現(xiàn)在:
           *    auto_ptr<Derived>  func_returning_auto_ptr(.....);
           *    ...
           *    auto_ptr<Base> ptr = func_returning_auto_ptr(.....);
    其實應(yīng)該是:
           *    auto_ptr<Derived>  func_returning_auto_ptr(.....);
           *    ...
           *    auto_ptr<Base> ptr(func_returning_auto_ptr(.....));   or   auto_ptr<Derived> ptr = func_returning_auto_ptr ;
    不要小看這點改動,上面的那種方案是編譯不過去的。因為上面的方案里需要轉(zhuǎn)換兩次再調(diào)用一次拷貝構(gòu)造函數(shù),這違背了C++最多轉(zhuǎn)換一次的限制。
    最后, 或許你在VC下實驗的結(jié)果會和我說的不一樣, 這是因為VC在臨時對象這一點上對標(biāo)準(zhǔn)C++的支持不夠好,用臨時對象作參數(shù)的時候不加const也可以編譯通過.

    posted on 2009-07-05 21:33 so true 閱讀(1661) 評論(1)  編輯  收藏 所屬分類: C&C++

    評論

    # re: 構(gòu)造函數(shù)與const的關(guān)系  回復(fù)  更多評論   

    非常感謝,你寫的太好了
    2013-12-30 22:16 | 游客
    主站蜘蛛池模板: 国产jizzjizz视频免费看| 成年丰满熟妇午夜免费视频| 亚洲精品无码久久久久AV麻豆| 亚洲国产精品一区二区三区在线观看| 91嫩草免费国产永久入口| 亚洲精品资源在线| 精品香蕉在线观看免费| 日韩亚洲人成在线| 毛片免费观看的视频在线| 亚洲日本成本人观看| 日本不卡高清中文字幕免费| 久久久久久亚洲精品无码| 四虎永久免费影院| 精品乱子伦一区二区三区高清免费播放| 亚洲精品第一国产综合精品99| 国产精品福利在线观看免费不卡 | 2020久久精品亚洲热综合一本| 69堂人成无码免费视频果冻传媒| 亚洲一级毛片中文字幕| 妞干网免费视频在线观看| 精品亚洲成a人在线观看| JLZZJLZZ亚洲乱熟无码| 久久精品国产影库免费看| 亚洲毛片免费观看| 精品国产免费一区二区| 国产特黄一级一片免费| 亚洲精品不卡视频| 日日操夜夜操免费视频 | 两性色午夜视频免费播放| 亚洲色四在线视频观看| 性一交一乱一视频免费看| 免费一级毛片在线播放放视频 | 好爽…又高潮了毛片免费看 | 国产免费爽爽视频在线观看 | 羞羞网站在线免费观看| 久久亚洲国产欧洲精品一| 噼里啪啦免费观看高清动漫4| 国产精品亚洲一区二区三区久久| 亚洲深深色噜噜狠狠爱网站| 国产曰批免费视频播放免费s| 一级毛片免费不卡直观看|