• <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.¢%

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

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

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

            第一種方法:

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

            第二種方法:

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

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

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

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

            ????因?yàn)镃Member有一個(gè)顯式聲明的構(gòu)造函數(shù),編譯器不產(chǎn)生一個(gè)缺省構(gòu)造函數(shù)(不帶參數(shù)),所以沒(méi)有一個(gè)整數(shù)就無(wú)法創(chuàng)建CMember的一個(gè)實(shí)例。

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

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

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

            {
            """
            }

            ????沒(méi)有其它辦法將參數(shù)傳遞給m_member,如果成員是一個(gè)常量對(duì)象或者引用也是一樣。根據(jù)C++的規(guī)則,常量對(duì)象和引用不能被賦值,它們只能被初始化。

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

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

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

            ????在它們之間有什么不同嗎?是的。編譯器總是確保所有成員對(duì)象在構(gòu)造函數(shù)體執(zhí)行之前被初始化,因此在第一個(gè)例子中編譯的代碼將調(diào)用CString::Cstring來(lái)初始化m_str,這在控制到達(dá)賦值語(yǔ)句前完成。在第二個(gè)例子中編譯器產(chǎn)生一個(gè)對(duì)CString::?CString(LPCTSTR)的調(diào)用并將"Hi,how?are?you."傳遞給這個(gè)函數(shù)。結(jié)果是在第一個(gè)例子中調(diào)用了兩個(gè)CString函數(shù)(構(gòu)造函數(shù)和賦值操作符),而在第二個(gè)例子中只調(diào)用了一個(gè)函數(shù)。

            ????在CString的例子里這是無(wú)所謂的,因?yàn)槿笔?gòu)造函數(shù)是內(nèi)聯(lián)的,CString只是在需要時(shí)為字符串分配內(nèi)存(即,當(dāng)你實(shí)際賦值時(shí))。但是,一般而言,重復(fù)的函數(shù)調(diào)用是浪費(fèi)資源的,尤其是當(dāng)構(gòu)造函數(shù)和賦值操作符分配內(nèi)存的時(shí)候。在一些大的類里面,你可能擁有一個(gè)構(gòu)造函數(shù)和一個(gè)賦值操作符都要調(diào)用同一個(gè)負(fù)責(zé)分配大量?jī)?nèi)存空間的Init函數(shù)。在這種情況下,你必須使用初始化列表,以避免不要的分配兩次內(nèi)存。
            ????在內(nèi)建類型如ints或者longs或者其它沒(méi)有構(gòu)造函數(shù)的類型下,在初始化列表和在構(gòu)造函數(shù)體內(nèi)賦值這兩種方法沒(méi)有性能上的差別。不管用那一種方法,都只會(huì)有一次賦值發(fā)生。有些程序員說(shuō)你應(yīng)該總是用初始化列表以保持良好習(xí)慣,但我從沒(méi)有發(fā)現(xiàn)根據(jù)需要在這兩種方法之間轉(zhuǎn)換有什么困難。在編程風(fēng)格上,我傾向于在主體中使用賦值,因?yàn)橛懈嗟目臻g用來(lái)格式化和添加注釋,你可以寫(xiě)出這樣的語(yǔ)句:

            x=y=z=0;

            或者

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

            注意第二個(gè)片斷絕對(duì)是非面向?qū)ο蟮摹?

            ????當(dāng)我考慮初始化列表的問(wèn)題時(shí),有一個(gè)奇怪的特性我應(yīng)該警告你,它是關(guān)于C++初始化類成員的,它們是按照聲明的順序初始化的,而不是按照出現(xiàn)在初始化列表中的順序。

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

            ????你可能以為上面的代碼將會(huì)首先做m_y=i,然后做m_x=m_y,最后它們有相同的值。但是編譯器先初始化m_x,然后是m_y,,因?yàn)樗鼈兪前催@樣的順序聲明的。結(jié)果是m_x將有一個(gè)不可預(yù)測(cè)的值。這個(gè)例子是故意這樣設(shè)計(jì)來(lái)說(shuō)明這一點(diǎn)的,然而這種bug會(huì)很自然地出現(xiàn)。有兩種方法避免它,一個(gè)是總是按照你希望它們被初始化的順序來(lái)聲明成員,第二個(gè)是,如果你決定使用初始化列表,總是按照它們聲明的順序羅列這些成員。這將有助于消除混淆。
            青青青青久久精品国产h| 久久e热在这里只有国产中文精品99| 久久99热这里只有精品66| 亚洲中文字幕无码久久2020| 996久久国产精品线观看| 久久天天躁狠狠躁夜夜不卡| 少妇久久久久久被弄高潮| 91精品国产色综久久| 久久夜色精品国产亚洲| 色综合久久久久网| 久久精品日日躁夜夜躁欧美| 国产精自产拍久久久久久蜜 | 国产精品无码久久四虎| 国产激情久久久久久熟女老人| 久久精品免费观看| 久久偷看各类wc女厕嘘嘘| 无码任你躁久久久久久| AAA级久久久精品无码区| 性欧美丰满熟妇XXXX性久久久| 久久综合成人网| 88久久精品无码一区二区毛片 | 久久久久国产视频电影| 久久超乳爆乳中文字幕| 久久精品青青草原伊人| 日批日出水久久亚洲精品tv| 久久亚洲精品视频| 高清免费久久午夜精品| 人妻精品久久久久中文字幕一冢本| 久久免费大片| 久久人人爽人爽人人爽av| 久久中文字幕一区二区| 成人国内精品久久久久一区| 亚洲国产欧洲综合997久久| 久久成人小视频| 狠狠色丁香婷婷久久综合| 久久天天日天天操综合伊人av| 国产精品一区二区久久精品无码| 婷婷综合久久狠狠色99h| 嫩草影院久久99| 国内精品免费久久影院| 亚洲性久久久影院|