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

            高山流水

            ----- 要黑就黑徹底

            Inside The C++ Object Model 學(xué)習(xí)筆記 -- The Semantics Of Constructors

            2.1 Default Constructor 的構(gòu)造操作
            ??? 按照C++ Annotated Reference Manaual 的說(shuō)法:"Default constructor... 在需要的時(shí)候被編譯器產(chǎn)生出來(lái)". 這里的關(guān)鍵字是:“在需要的時(shí)候”。
            ??? C++ Standard[ISO-C++95]中又有如下的聲明:對(duì)于class X, 如果沒(méi)有任何user-declared constructor,那么會(huì)有一個(gè)default constructor 被暗中聲明出來(lái)....一個(gè)被暗中聲明出來(lái)的default constructor 將是一個(gè)trival的constructor"。 這里我覺(jué)得主要是“user-declared constructor”,它包括用戶所定義的所有的constructor還有其它的一些有virtual關(guān)鍵字的操作。這樣下面的四種情況下由編譯器生成的constructor是notrival default constructor:
            ???
            ??? 1. 帶有 Default Constructor 的 Member Class Object(帶有缺省構(gòu)造函數(shù)的類成員對(duì)象)
            ??? 如果一個(gè)類的帶有一個(gè)或多個(gè)的類成員對(duì)象,而類成員對(duì)象又有構(gòu)造函數(shù),那么就會(huì)生成該類就會(huì)生成一個(gè)notrival default constructor 構(gòu)造函數(shù)。 成員對(duì)象的構(gòu)造函數(shù)的調(diào)用是按成員對(duì)象的聲明順序執(zhí)行的。例如:

            class ?Foo? {? public :?Foo(),?Foo( int )?.?} ;
            class ?Bar? {? public :?Foo?foo;? char ? * str;?} ;?
            ??
            void ?foo_bar()
            {
            ???????Bar?bar;?
            // ?Bar::foo在這里被初始化(調(diào)用Foo的缺省構(gòu)造行數(shù):?Foo:Foo())
            ??????
            ??????
            //
            ????? if ?(str)? {?} ??.?
            ???}

            ????
            ??? 對(duì)于有多個(gè)成員對(duì)象的類,則按成員對(duì)象在類的聲明中的順序調(diào)用它們的構(gòu)造函數(shù)。
            ??????
            ??? 2. 帶有 Default Constructor 的 Base Class(帶有缺省構(gòu)造函數(shù)的基類對(duì)象)????? ?指的是一個(gè)沒(méi)有任何constructorsrs的類派生自一個(gè)帶有“default constructor”的基類。 如果類存在多個(gè)構(gòu)造函數(shù)的話,那么編譯器也會(huì)擴(kuò)充現(xiàn)有的每一個(gè)構(gòu)造函數(shù),將調(diào)用基類的default constructor的代碼加入到其中。
            ???????
            ??? 3. 帶有一個(gè) Virtual Function 的 Class
            ??? 這樣的virtual Function可以使繼承來(lái)的或直接定義的。 編譯器在編譯期間會(huì)做如下工作
            ??? a. 生成一個(gè)virtual Function talbe(vtbl), 用來(lái)存放class 的virtual function的地址
            ??? b. 在每一個(gè)class object中,添加一個(gè)額外的pointer member(vptr),它指向class vtbl的地址
            ???
            ??? 4. 帶有一個(gè) Virtual Base Class 的 Class
            ??? 這種情況是在導(dǎo)出類的安插一個(gè)virtual base classes的指針,用來(lái)在運(yùn)行時(shí)存取virtual base class 的成員。例如:

            ?1?????class?X?{?public:?int?i;?};?
            ?2?????class?A?:?public?virtual?X???{?public:?int?j;?};?
            ?3?????class?B?:?public?virtual?X???{?public:?double?d;?};?
            ?4?????class?C?:?public?A,?public?B?{?public:?int?k;?};?
            ?5?
            ?6?????//?cannot?resolve?location?of?pa->X::i?at?compile-time?
            ?7?????void?foo(?const?A*?pa?)?{?pa->i?=?1024;?}?
            ?8?????//?在編譯期可能生成如下形式:
            ?9?????//?void?foo(const?A*?pa)?{?pa->_vbcX->i?=?1024;?}?//?_vbcX:?virtual?base?class?X
            10?????
            11?????main()?
            12?????{?
            13?????????foo(?new?A?);?
            14?????????foo(?new?C?);?
            15?????
            16?????????//??
            17?????}
            18?
            19?

            ????
            ??? 注意: 在合成的default constructor中,只有base class subobjects和member class objects會(huì)被初始化,其它所有的nostatic data member都不會(huì)執(zhí)行初始化的操作.要我們自己手動(dòng)的去執(zhí)行初始化的操作.

            ??? 其實(shí)把握一個(gè)原則:要不要合成一個(gè)構(gòu)造函數(shù),依據(jù)編譯器的需要與否,合成出來(lái)的constructor也只是完成那些編譯器所需求。
            ???
            ??? 兩個(gè)錯(cuò)誤的觀點(diǎn):
            ?i. 任何時(shí)候,如果沒(méi)有定義default constructor,就會(huì)被合成一個(gè)出來(lái)。(而是根據(jù)編譯器的需要決定是否生成一個(gè)deault constructor)
            ?ii. 編譯器生成出來(lái)的default constructor會(huì)明確的初始化每類中的每一個(gè)data member.


            2.2 Copy Constructor的構(gòu)建操作
            ??? 有三種情況下會(huì)有一個(gè)Copy Constructor的操作:
            ?i.?? 對(duì)一個(gè)object做明確的初始化操作??// class X{ ....};?? X x;??? X xx = x;
            ?ii.? 當(dāng)某個(gè)object作為參數(shù)傳遞給某個(gè)函數(shù)??// void foo(X x) { .... }
            ?iii. 函數(shù)傳回一個(gè)class object對(duì)象??// void foo(){ X xx; return xx;}

            ??? 1. Default Memberwise Initialization(缺省的按成員初始化)
            ??? 如果一個(gè)類沒(méi)有explicit copy constructor時(shí), class object在執(zhí)行copy constructor時(shí),內(nèi)部以default member initialization的手法來(lái)完成,就是把每一個(gè)內(nèi)建或者派生而來(lái)的data member的值從某個(gè)object 拷貝一份到另一個(gè)object身上,對(duì)member class object是以遞歸的方式調(diào)用memberwise initialization的。
            ???
            ??? 這種初始化是通過(guò)在必要時(shí)生成一個(gè)copy constructor或通過(guò) bitwise copy 來(lái)完成的。 如果要通過(guò)bitwise來(lái)完成這這樣的操作,那么必須表現(xiàn)出bitwise copy semantise.?
            ???
            ??? C++ Standard中也把copy constructor分成trial 和notrivial兩種類型,只有notrivial的實(shí)體才會(huì)被合成于程序中。決定一個(gè)copy constructor是否為trivial在于類是否表現(xiàn)出所謂的"Bitwise copy sematics".
            ???
            ??? 2. Bitwise Copy Semantics
            ??? 在 bitwise copy sematics 下,不會(huì)構(gòu)造出一個(gè)default copy constructor. 例如:
            ?

            ?1????class?Word
            ?2?????{
            ?3?????public:?
            ?4?????????Word(const?char*);
            ?5?????????~Word(){?delete?[]str;?}
            ?6?????????//
            ?7?????private:
            ?8?????????int?cnt;
            ?9?????????char?*str;
            10?????}??
            11?????以上的是一個(gè)表現(xiàn)出Bitwise?copy?sematics的類,而以下是一個(gè)沒(méi)有表現(xiàn)出bitwise?copy?sematics的類
            12?????class?Word
            13?????{
            14?????public:?
            15?????????Word(const?char*);
            16?????????~Word(){?delete?[]str;?}
            17?????????//
            18?????private:
            19?????????int?cnt;
            20?????????String?str;
            21?????}
            22?????
            23?????class?String?
            24?????{
            25?????public:?
            26?????????String(const?char*);
            27?????????String(const?string&);?//?String的顯示copy?constructor
            28?????????~String();
            29?????????//.
            30?????}
            31?????這種情況下會(huì)合成一個(gè)copy?constructor以調(diào)用class?String?object的copy?constructor.
            32?????inline?Word::Word(const?Word&?wd)
            33?????{
            34?????????str.String::String(wd.str);
            35?????????cnt?=?wd.cnt;
            36?????}????
            37?

            ???????
            ??? 3. 不表現(xiàn)出Bitwise Copy Sematics的特性的情況
            ??? 以下的幾種情況class不表現(xiàn)出 Bitwise Sematics:
            ??????? a. 當(dāng)class 內(nèi)含有一個(gè)member object, 而后者的class 聲明有一個(gè)copy constructor時(shí)(合成或聲明的都可以),就不表現(xiàn)出Bitwise Sematics
            ??????? b. 當(dāng)class 繼承自一個(gè)base class, 而后者存在有一個(gè)copy constructor(合成或聲明的都可以), 就不表現(xiàn)出Bitwise Sematics.
            ??????? c. 當(dāng)類聲明了一個(gè)或多個(gè)virtual function時(shí)
            ??????? d. 當(dāng)class派生自一個(gè)繼承創(chuàng)串鏈,其中有一個(gè)或多個(gè)virtual base classes時(shí), 類就不表現(xiàn)出Bitwise Sematics
            ??? 這四種情況和default constructor生成的是否一個(gè)trivial是一樣的, 也是滿足編譯器的需求。
            ??????
            ??? 4. 重新設(shè)定Virtual Table 的指針
            ??? 對(duì)于以上:當(dāng)類聲明了一個(gè)或多個(gè)virtual function的情況,程序會(huì)為類對(duì)象做如下兩個(gè)擴(kuò)張操作:
            ??????? (1) 增加一個(gè)vtbl的指針,內(nèi)含virtual function的指針地址。
            ??????? (2) 在類對(duì)象內(nèi)安插一個(gè)vptr指針,指向virtual function table.
            ??? 對(duì)于把一個(gè)base class object 以其derived class object的值初始化操作的時(shí)候,會(huì)發(fā)生切割(sliced)操作。這時(shí)也要保證vtbl的正確和vtpr的正確性。
            ???
            ??? 5. 處理Virtual Base Class Subobject
            ??? 如果一個(gè)class object是以另外一個(gè)object作為初始值的話,而后者又有一個(gè)virtual base class suboject的話,那么也會(huì)使bitwise copy sematics失效。例如:

            ?1?????class?Raccoon?:?public?virtual?ZooAnimal{
            ?2?????public:
            ?3???Raccoon(){??;?}
            ?4???Raccoon(int?val)?{?;?}
            ?5???private:
            ?6???//?
            ?7?????};
            ?8?
            ?9?????class?RedPanda?:?public?Raccoon{
            10?????public:
            11???RedPanda()?{?.;?}
            12???RedPanda(int?val)?{?.;?}
            13???private:
            14???//?
            15?????};
            16?????執(zhí)行如下操作時(shí)會(huì)要求合成一個(gè)copy?constructor:
            17?????RedPanda?little_red;
            18?????Raccoon?little_critter?=?little_re;??//?這里編譯器必須明確的把little_critter的virtual?base?class?pointer/offset初始化。
            19?
            20?????//?如果只是這樣的操作用bitwise?copy?就可以了
            21?????Raccoon?rocky;
            22?????Raccoon?little_critter?=?rocky;???//?用簡(jiǎn)單的bitwise?copy?就可以搞定了
            23?
            24?


            2.3 程序轉(zhuǎn)化語(yǔ)義學(xué)(Program Transformation Semantics)
            ?指的是程序在執(zhí)行的是候要做的類型和操作的轉(zhuǎn)換。 下面例子反映了三種轉(zhuǎn)換操作:

            ?

            ?1??#include?"X.h"
            ?2?
            ?3??X?foo(?X?x0)
            ?4??{
            ?5???X?xx;
            ?6?
            ?7???//?.,?對(duì)xx和x0進(jìn)行操作
            ?8?
            ?9???return?XX;
            10??}
            11?

            ?

            ?1. 明確的初始化操作(Explicit Initialization)
            ?例如:

            1 X?x0
            2 ? void ?foo_bar()
            3 ? {
            4 ??X?x1(x0);
            5 ??X?x2? = ?x0;
            6 ??X?x3? = ?X(x0);
            7 ?}

            8

            ?
            ?對(duì)程序做兩個(gè)階段的轉(zhuǎn)化:
            ?i. 重寫(xiě)每一個(gè)定義,其中的初始化操作都會(huì)被剝除
            ?ii. 類的Copy constructor操作會(huì)被安插進(jìn)去
            ?轉(zhuǎn)化后可能成為這樣的(偽碼):
            ?這也就是說(shuō)前面三種的初始化操作都會(huì)轉(zhuǎn)換成Explicit Initialization.

            ?1??void?foo_bar()
            ?2??{
            ?3???X?x1;?
            ?4???X?x2;
            ?5???X?x3;
            ?6?
            ?7???x1.X::X(x0);
            ?8???x2.X::X(x0);
            ?9???x3.X::X(x0);
            10??}
            11?
            12?

            ?2. 參數(shù)的初始化(Argument Initialization)
            ?例如下面:

            ?1??void?foo(X?x0){?;?}
            ?2??void?call()
            ?3??{
            ?4???X?xx;
            ?5?
            ?6???//?.?xxx?初始化及其操作
            ?7?
            ?8???foo(xx);
            ?9??}
            10??轉(zhuǎn)換后的操作為:
            11??void?call()
            12??{
            13???X?xx;
            14?
            15???X?__temp0;
            16???__temp0.X::X(xx);
            17???foo(__temp0);????????????????//?foo?函數(shù)應(yīng)變成:void?foo(X&?x0);
            18???__temp0.X::~X();??
            19??}
            20?
            21?

            ?這就是為什么當(dāng)傳值到孫數(shù)的時(shí)候,不會(huì)把函數(shù)內(nèi)對(duì)傳入值的操作結(jié)果不會(huì)被修改,因?yàn)樗诤瘮?shù)內(nèi)本來(lái)修改的就不是外部傳人的那個(gè)變量。


            ?3. 返回值的初始化(Return Value Initialization)
            ?例如:
            ?X bar()
            ?{
            ??X xx;
            ??// ....
            ??return xx;
            ?}?
            ?
            ?轉(zhuǎn)化為如下偽碼:
            ?void bar(X& __result)
            ?{
            ??X xx;
            ??xx.X::X();?? // 編譯器生成的一個(gè)缺省的構(gòu)造函數(shù)調(diào)用

            ??// 處理 ....

            ??__result.X::X(xx);??? // 編譯器生成的copy constructor調(diào)用操作
            ??return;
            ?}
            ?
            ?如下的操作轉(zhuǎn)化為:
            ?void foo()
            ?{
            ??X xx = bar();
            ?}

            ?被轉(zhuǎn)化為:
            ?void foo()
            ?{
            ??X xx;
            ??bar(xx);?? // 注意這里不用執(zhí)行 default constructor
            ?}
            ?
            ?針對(duì)這種轉(zhuǎn)換,可以從使用層面上進(jìn)行優(yōu)化和在編譯器層面上做優(yōu)化操作。在編譯器層面上的操作就是采用NRV(Named Return Value)技術(shù)。
            ?如:
            ?x bar()
            ?{
            ??X xx;
            ??// ....
            ??return xx;
            ?}
            ?優(yōu)化為:
            ?void bar(X& __result)
            ?{
            ??__result.X::X();

            ??//....? 直接的處理 __result

            ??//
            ??return ;
            ?}?

            2.4 成員初始化隊(duì)伍(Member Initialization List)
            ?這里有兩點(diǎn)要注意:
            ?1. 以下的四種情況下必須使用 member intialization list
            ??I.?? 當(dāng)初始化一個(gè)reference member時(shí)
            ??II.? 當(dāng)初始化一個(gè)const member時(shí)
            ??III. 當(dāng)初始化一個(gè)base class 的constructor,而它擁有一組參數(shù)時(shí)
            ??IV.? 當(dāng)調(diào)用一個(gè)member class的constructor, 而它擁有一組參數(shù)時(shí)

            ??其它情況下可以用在構(gòu)造函數(shù)內(nèi)初始化也可以
            ?
            ?2. 關(guān)于初始化的次序問(wèn)題:
            ??編譯器的初始化的順序是按member聲明次序來(lái)依次的初始化的。它會(huì)安插一些代碼到構(gòu)造函數(shù)內(nèi),并放在任何其它用戶初始化的代碼之前.

            ?

            posted on 2006-10-30 14:33 猩猩 閱讀(322) 評(píng)論(0)  編輯 收藏 引用 所屬分類: C&C++語(yǔ)言

            久久久中文字幕日本| 国产精品免费久久久久电影网| 99久久伊人精品综合观看| 久久99精品综合国产首页| 国产精品天天影视久久综合网| 久久久噜噜噜久久熟女AA片| 婷婷久久综合| 久久久久久噜噜精品免费直播| 久久久久亚洲AV片无码下载蜜桃| 香蕉99久久国产综合精品宅男自 | 一本色道久久88精品综合| 久久久久亚洲精品日久生情 | 久久人与动人物a级毛片| 精品午夜久久福利大片| 亚洲国产成人久久精品99| 久久99国产综合精品| 青春久久| 久久精品国产福利国产琪琪| 久久精品人人槡人妻人人玩AV| 日韩亚洲国产综合久久久| 99久久精品免费看国产| 久久久精品国产sm调教网站| 一97日本道伊人久久综合影院| 91精品国产色综久久| 国内精品久久久久影院日本| 精品多毛少妇人妻AV免费久久 | 国产午夜电影久久| 精品久久一区二区三区| 国产91色综合久久免费分享| 色8久久人人97超碰香蕉987| 狠狠色婷婷久久综合频道日韩| 日韩中文久久| 欧美精品九九99久久在观看| 日韩久久无码免费毛片软件| 国产精品一区二区久久精品无码| 精品久久香蕉国产线看观看亚洲 | 伊人久久大香线蕉综合影院首页| 一级女性全黄久久生活片免费| 三级韩国一区久久二区综合 | 手机看片久久高清国产日韩| 无码8090精品久久一区|