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

            S.l.e!ep.¢%

            像打了激速一樣,以四倍的速度運轉,開心的工作
            簡單、開放、平等的公司文化;尊重個性、自由與個人價值;
            posts - 1098, comments - 335, trackbacks - 0, articles - 1
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            C++ 類成員初始化的兩種方法

            Posted on 2009-09-07 18:19 S.l.e!ep.¢% 閱讀(561) 評論(0)  編輯 收藏 引用 所屬分類: C++
            在使用C++編程的過程當中,常常需要對類成員進行初始化,通常的方法有兩種:

            第一種方法:

            CMYClass::CSomeClass()
            {
            ????x=0;
            ????y=1;
            }

            第二種方法:

            CSomeClass::CSomeClass()?:?x(0),?y(1)
            {
            }

            本文將要探討這兩種方法的異同以及如何使用這兩種方法。

            ????從技術上說,第二種方法比較好,但是在大多數情況下,兩者實際上沒有什么區別。第二種語法被稱為成員初始化列表,之所以要使用這種語法有兩個原因:一個原因是必須這么做,另一個原因是出于效率考慮。
            ????讓我們先看一下第一個原因——必要性。設想你有一個類成員,它本身是一個類或者結構,而且只有一個帶一個參數的構造函數。

            class?CMember?{
            public:
            ????CMember(int?x)?{?...?}
            };

            ????因為CMember有一個顯式聲明的構造函數,編譯器不產生一個缺省構造函數(不帶參數),所以沒有一個整數就無法創建CMember的一個實例。

            CMember*?pm?=?new?CMember;????????//?出錯!!
            CMember*?pm?=?new?CMember(2);?????//?OK

            ????如果CMember是另一個類的成員,你怎樣初始化它呢?答案是你必須使用成員初始化列表。

            class?CMyClass?{
            ????CMember?m_member;
            public:
            ????CMyClass();
            };
            //?必須使用初始化列表來初始化成員?m_member
            CMyClass::CMyClass()?:?m_member(2)

            {
            """
            }

            ????沒有其它辦法將參數傳遞給m_member,如果成員是一個常量對象或者引用也是一樣。根據C++的規則,常量對象和引用不能被賦值,它們只能被初始化。

            ????使用初始化列表的第二個原因是出于效率考慮,當成員類具有一個缺省的構造函數和一個賦值操作符時。MFC的CString提供了一個完美的例子。假定你有一個類CMyClass具有一個CString類型的成員m_str,你想把它初始化為"Hi,how?are?you."。你有兩種選擇:

            CMyClass::CMyClass()?{
            //?使用賦值操作符
            //?CString::operator=(LPCTSTR);
            m_str?=?_T("Hi,how?are?you.");
            }

            //?使用初始化列表
            //?和構造函數?CString::CString(LPCTSTR)
            CMyClass::CMyClass()?:?m_str(_T("Hi,how?are?you."))
            {
            }

            ????在它們之間有什么不同嗎?是的。編譯器總是確保所有成員對象在構造函數體執行之前被初始化,因此在第一個例子中編譯的代碼將調用CString::Cstring來初始化m_str,這在控制到達賦值語句前完成。在第二個例子中編譯器產生一個對CString::?CString(LPCTSTR)的調用并將"Hi,how?are?you."傳遞給這個函數。結果是在第一個例子中調用了兩個CString函數(構造函數和賦值操作符),而在第二個例子中只調用了一個函數。

            ????在CString的例子里這是無所謂的,因為缺省構造函數是內聯的,CString只是在需要時為字符串分配內存(即,當你實際賦值時)。但是,一般而言,重復的函數調用是浪費資源的,尤其是當構造函數和賦值操作符分配內存的時候。在一些大的類里面,你可能擁有一個構造函數和一個賦值操作符都要調用同一個負責分配大量內存空間的Init函數。在這種情況下,你必須使用初始化列表,以避免不要的分配兩次內存。
            ????在內建類型如ints或者longs或者其它沒有構造函數的類型下,在初始化列表和在構造函數體內賦值這兩種方法沒有性能上的差別。不管用那一種方法,都只會有一次賦值發生。有些程序員說你應該總是用初始化列表以保持良好習慣,但我從沒有發現根據需要在這兩種方法之間轉換有什么困難。在編程風格上,我傾向于在主體中使用賦值,因為有更多的空間用來格式化和添加注釋,你可以寫出這樣的語句:

            x=y=z=0;

            或者

            memset(this,0,sizeof(this));

            注意第二個片斷絕對是非面向對象的。

            ????當我考慮初始化列表的問題時,有一個奇怪的特性我應該警告你,它是關于C++初始化類成員的,它們是按照聲明的順序初始化的,而不是按照出現在初始化列表中的順序。

            class?CMyClass?{
            ????CMyClass(int?x,?int?y);
            ????int?m_x;
            ????int?m_y;
            };
            CMyClass::CMyClass(int?i)?:?m_y(i),?m_x(m_y)
            {
            }

            ????你可能以為上面的代碼將會首先做m_y=i,然后做m_x=m_y,最后它們有相同的值。但是編譯器先初始化m_x,然后是m_y,,因為它們是按這樣的順序聲明的。結果是m_x將有一個不可預測的值。這個例子是故意這樣設計來說明這一點的,然而這種bug會很自然地出現。有兩種方法避免它,一個是總是按照你希望它們被初始化的順序來聲明成員,第二個是,如果你決定使用初始化列表,總是按照它們聲明的順序羅列這些成員。這將有助于消除混淆。
            欧美精品九九99久久在观看| 久久久久久久久无码精品亚洲日韩| 精品国产VA久久久久久久冰| 国产精品久久久久影院色| 国产精品欧美久久久久无广告| 无码国内精品久久人妻麻豆按摩| 亚洲精品成人网久久久久久| 无码精品久久久天天影视| 国产福利电影一区二区三区,免费久久久久久久精 | 色噜噜狠狠先锋影音久久| 日本精品久久久久影院日本 | 久久久久se色偷偷亚洲精品av | 久久久久av无码免费网| 久久国产成人精品麻豆| 久久精品国产男包| 91精品婷婷国产综合久久| 久久人人添人人爽添人人片牛牛| 久久精品国产精品国产精品污| 久久青青草视频| 久久精品国产一区二区| 久久99精品国产一区二区三区| 久久精品国产99久久久古代| 久久亚洲中文字幕精品一区| 人人狠狠综合久久亚洲88| 久久亚洲春色中文字幕久久久| 美女久久久久久| 日韩美女18网站久久精品| 国产精品免费久久| 99久久综合狠狠综合久久| 久久免费国产精品一区二区| 精品久久久噜噜噜久久久| 亚洲AV无码成人网站久久精品大| 久久久久久综合网天天| 久久久久国产精品人妻| 久久久一本精品99久久精品88| 亚洲精品乱码久久久久久不卡| 久久激情亚洲精品无码?V| 色综合久久天天综线观看| 欧美国产成人久久精品| 久久五月精品中文字幕| 久久久精品久久久久久|