C++ Default Constructor語(yǔ)意

先引用《深度探索C++對(duì)象模型》中的一段話:

C++ 新手一般有2個(gè)誤解
1 任何class如果沒(méi)有定義default constructor,就會(huì)被合成出一個(gè)來(lái)
2 編譯器合成出來(lái)的default constructor會(huì)顯示設(shè)定class類每一個(gè)data member的默認(rèn)值。
如你所見(jiàn),沒(méi)有一個(gè)是真的。

有下列4種情況,編譯器必須會(huì)未聲明的constructor合成一個(gè)“default constructor”, 被合成出來(lái)的constructor只能滿足編譯器需要而不是程序需要。

1 "帶有Default Constructor"的member class object
class Foo{
    public: 
        Foo();
        Foo(int);
};
class Bar
{
    public:
        Foo foo;
        char *str;
};

這種情況下,編譯器會(huì)為class Bar 合成一個(gè)default constructor,被合成的default constructor內(nèi)含必要的代碼,能夠調(diào)用class Foo的default constructor來(lái)處理Bar::foo。至于*str的初始化(程序的需要),編譯器并不會(huì)管。
偽代碼:

inline Bar::Bar()
{
    foo.Foo::Foo();
}

但是如果Bar已經(jīng)顯示定義了一個(gè)默認(rèn)構(gòu)造函數(shù),比如

Bar()  {  str = nullptr;  }

現(xiàn)在程序的需求已經(jīng)滿足了,但是編譯器還需要初始化member object foo。這是,編譯器不能定義default constructor了,只能在程序員定義的構(gòu)造函數(shù)安插一些代碼,確認(rèn)user code被執(zhí)行之前,先調(diào)用default constructor。類似偽代碼:

Bar  { 
/*  
    插入的代碼
    foo.Foo::Foo();  
*/
    str = nullptr; 
 }
class A  {  public A()  {  }  };
class B  {  public B(int)  {  }  };
class C  {  public C()  {  }  };
class D  {
    public:
        D():  b(int)  {  }
    public:
         A a;
         B b;
         C c;
};

這種情況是D的構(gòu)造函數(shù)會(huì)被改造為:

D():b(int) {
    a.A::A();
    b.B::B(int);
    c.C::C();
    // 其他
}

注意順序是按照聲明順序來(lái)的。

2 "帶有Default Constructor"的Base Class

類似道理,如果沒(méi)有任何constructors的class繼承自一個(gè)帶有Defaultor Constructor的Base class, 那么derived class的default constructorh會(huì)被合成出來(lái),調(diào)用Base class的defaultor constructor。

3 "帶有Virtual Function"的Class
class Widget
{
  public:
      virtual void flip() = 0;
};
class Bell : public Widget  {......}
class Whistle : public Widget {......}

void flip(const Widget& widget)  {  widget.flip();  }

void foo() {
    Bell b;
    Whistle w;
    
    filp(w);
    filp(b);
}

下面2個(gè)行為會(huì)在編譯期間發(fā)生:

  • 一個(gè)virtual function table(vptl)會(huì)被編譯器產(chǎn)生出來(lái),里面放class 的virtual function的地址。
  • 在每一個(gè)class object中,一個(gè)額外的pointer member(vptr)會(huì)被產(chǎn)生出來(lái),內(nèi)含vtbl地址。
    這一段可以結(jié)合另外2篇文章理解:
    C++ 對(duì)象模型分析
    C++ 虛函數(shù)表分析
4 "帶有一個(gè)Virtual Base Class"的Class

這塊還不熟悉,待更。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,545評(píng)論 19 139
  • Introduction to C++ (Season 1) Unit 1: Overview of C++ 第1...
    我是阿喵醬閱讀 2,830評(píng)論 0 7
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 34,664評(píng)論 18 399
  • 很實(shí)用的編程英語(yǔ)詞庫(kù),共收錄一千五百余條詞匯。 第一部分: application 應(yīng)用程式 應(yīng)用、應(yīng)用程序app...
    春天的蜜蜂閱讀 1,606評(píng)論 0 22
  • 早在幾個(gè)世紀(jì)前,印第安女孩因?yàn)榧彝ヘ毟F靠喂養(yǎng)山羊維持生計(jì)。愛(ài)思考的她對(duì)比驚奇發(fā)現(xiàn)以達(dá)米阿那為食物的山羊生殖繁衍能力...
    圈愛(ài)營(yíng)行閱讀 379評(píng)論 0 0

友情鏈接更多精彩內(nèi)容