• <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>

            8.8 構造函數(2) [翻譯]

            原文 from www.learncpp.com/cpp-tutorial/88-constructors-part-ii/

            私有構造函數

            偶爾,我們不想讓用戶在class外使用特殊的構造函數。為了實現這個想法,我們可以將構造函數設定為私有的。

               1: class Book
               2: {
               3: private:
               4:     int m_nPages;
               5:  
               6:     // This constructor can only be used by Book's members
               7:     Book() // private default constructor
               8:     {
               9:          m_nPages = 0;
              10:     }
              11:  
              12: public:
              13:     // This constructor can be used by anybody
              14:     Book(int nPages) // public non-default constructor
              15:     {
              16:         m_nPages = nPages;
              17:     }
              18: };
              19:  
              20: int main()
              21: {
              22:     Book cMyBook; // fails because default constructor Book() is private
              23:     Book cMyOtherBook(242); // okay because Book(int) is public
              24:  
              25:     return 0;
              26: }

            public的構造函數具有的一個問題是它們沒有提供任何控制一個特殊的類能夠被創建多少次的方法。如果一個public構造函數存在,就能夠人用戶的愿望實例化足夠多的類對象。通常限制用戶只能夠實例化一個特殊的類是有用的。有很多方式實現單例(singletons),最常用的是使用私有或保護的構造函數。

             

            Constructor chaining and initialization issues

            當你實例化一個新的對象的時候,對象構造函數被編譯器隱式調用。有兩個狀況可能是新手經常犯錯的地方:

            1)有時候,一個類具有一個能夠做另一個構造函數相同工作的構造函數,并增加額外的工作。處理器讓一個構造函數調用另一個構造函數,叫做constructor chaining。如果你嘗試這樣做,它能夠通過編譯,但是它將不能夠正確的工作,然后你就得花費大量的時間去找出原因,甚至使用debugger。但是,構造函數允許調用非構造函數。通常要小心,使用已經初始化的變量。

            (譯者加:這里C++中為什么不能使用constructor chaining呢,可以跟蹤一下下面這段代碼答案就出來了:

               1: #include <iostream>
               2: using namespace std;
               3:  
               4: class Foo 
               5: {
               6:     int m_nValue;
               7: public:
               8:     Foo() { m_nValue = 1; }
               9:     
              10:     // 這里沒用到a,因為只是一個示例
              11:     Foo(int a) { Foo(); }
              12:     
              13:     ~Foo() { cout << "destructed" << endl; }
              14:     
              15:     int getValue() { return m_nValue; }
              16: };
              17:  
              18: int main()
              19: {
              20:     Foo cTmp(1);
              21:     cout << cTmp.getValue1();
              22: }

            盡管你能將一個構造函數中的代碼復制到另一個構造函數中,重復性的代碼會使得你的類變得臃腫。最好的解決方法是創建一個非構造函數實現公共的初始化。

               1: class Foo
               2: {
               3: public:
               4:     Foo()
               5:     {
               6:         // code to do A
               7:     }
               8:  
               9:     Foo(int nValue)
              10:     {
              11:         // code to do A
              12:         // code to do B
              13:     }
              14: };

            變為

               1: class Foo
               2: {
               3: public:
               4:     Foo()
               5:     {
               6:         DoA();
               7:     }
               8:  
               9:     Foo(int nValue)
              10:     {
              11:         DoA();
              12:         // code to do B
              13:     }
              14:  
              15:     void DoA()
              16:     {
              17:         // code to do A
              18:     }
              19: };

            2)也許你想要一個成員函數實現將成員變量設定為默認值。因為你可能已經通過構造函數實現了,你也許會在成員函數中調用構造函數。但是這在C++中是不合法的。

            類似1)中實現的方式

               1: class Foo
               2: {
               3: public:
               4:     Foo()
               5:     {
               6:         Init();
               7:     }
               8:  
               9:     Foo(int nValue)
              10:     {
              11:         Init();
              12:         // do something with nValue
              13:     }
              14:  
              15:     void Init()
              16:     {
              17:         // code to init Foo
              18:     }
              19: };

            如果Init中有動態分配內存的情況,需要更加小心的對待了。在執行相應的操作之前,應該進行一定的檢測。避免錯誤的發生。

            posted on 2012-05-30 22:06 鐘謝偉 閱讀(1206) 評論(0)  編輯 收藏 引用

            <2012年5月>
            293012345
            6789101112
            13141516171819
            20212223242526
            272829303112
            3456789

            導航

            統計

            常用鏈接

            留言簿(1)

            隨筆檔案

            IT網站

            My Friends

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            伊人久久综合精品无码AV专区| 久久99国产精品久久99果冻传媒| 亚洲国产香蕉人人爽成AV片久久| 欧美激情精品久久久久久| 亚洲伊人久久大香线蕉综合图片| 精品国产一区二区三区久久久狼 | 精品国产99久久久久久麻豆| 久久亚洲春色中文字幕久久久| 精品国产综合区久久久久久 | 亚洲国产综合久久天堂| 奇米影视7777久久精品| 久久青青草原精品国产软件| 精品国产乱码久久久久久1区2区 | 日本精品久久久久中文字幕8 | 久久婷婷午色综合夜啪| 99久久精品这里只有精品| 久久www免费人成看片| 久久夜色精品国产亚洲av| 久久久久久免费一区二区三区| 漂亮人妻被中出中文字幕久久 | 一级做a爱片久久毛片| 久久精品水蜜桃av综合天堂| 久久婷婷五月综合成人D啪| 久久久久久国产a免费观看不卡| 久久国产精品久久| 久久99国产综合精品女同| 久久天堂AV综合合色蜜桃网| 久久九九兔免费精品6| 热久久视久久精品18| 婷婷久久综合九色综合绿巨人| 精品久久久久久国产免费了| 久久99国产精品成人欧美| 久久se这里只有精品| 久久久久99精品成人片牛牛影视| 国产精品久久久天天影视香蕉| 中文字幕亚洲综合久久2| 久久久久国色AV免费观看| 少妇久久久久久被弄到高潮| 亚洲欧美久久久久9999 | 精品国产乱码久久久久久郑州公司| 亚洲色大成网站www久久九|