簡體   English   中英

構造函數調用繼承的類

[英]Constructor call in inherited classes

請考慮以下代碼:

class A {
public:
    int a;
};

class B : public A {
public:
    B() { std::cout << "B[" << a << "]" << std::endl; }
};

class C : public B {
public:
    C() { std::cout << "C[" << a << "]" << std::endl; }
};

int main(int argc, char *argv[]) {

    B();
    std::cout << std::endl;
    C();

}

它的輸出程序用g ++編譯(Ubuntu / Linaro 4.6.3-1ubuntu5)4.6.3:

B[0]

B[-2097962768]
C[-2097962768]

我發現獲得第二個調用的唯一方法C() - 初始化其值是向構造函數添加顯式調用,如:

class B : public A {
public:
    B() : A() { std::cout << "B[" << a << "]" << std::endl; }
};

class C : public B {
public:
    C() : B() { std::cout << "C[" << a << "]" << std::endl; }
};

雖然我知道調用每個前一個類的默認構造函數會初始化值,但是當沒有指定任何內容時,我無法看到被調用的內容。

默認構造函數不是默認調用的 - 因此它的句柄?

使用您的原始代碼

class A {
public:
    int a;
};

class B : public A {
public:
    B() { std::cout << "B[" << a << "]" << std::endl; }
};

A的成員未初始化,因為您尚未指定任何初始化。 通常,在C ++中,您不需要為不需要的東西付費。 因此,默認情況下,您沒有為POD成員進行初始化(但是,您確實為具有構造函數的成員獲取了它,因為已指定了初始化)。

在隨后的“顯式構造函數調用”代碼中

class B : public A {
public:
    B() : A() { std::cout << "B[" << a << "]" << std::endl; }
};

您已指定A基類子對象的值初始化 實際上,這減少到零初始化。

這與以下相同

A* p = new A;

A* p = new A();

后者值初始化對象。


Standardese ...

C ++11§8.5/ 10
“初始值為空集括號的對象,即() ,應進行值初始化。”

C ++11§8.5./7
an object of type T means: “對T類型的對象進行意味着:
- 如果T是具有用戶提供的構造函數(12.1)的(可能是cv限定的)類類型(第9節),則調用T的默認構造函數(如果T沒有可訪問的默認構造函數,則初始化是錯誤的);
- 如果T是一個(可能是cv限定的)非聯合類類型而沒有用戶提供的構造函數,那么該對象是零初始化的,如果T的隱式聲明的默認構造函數是非平凡的,則調用該構造函數。
- 如果T是數組類型,則每個元素都是值初始化的;
- 否則,對象被零初始化。
值初始化的對象被視為構造,因此受本國際標准的規定適用於“構造”對象,“構造函數已完成的對象”等,即使沒有為該對象調用構造函數也是如此。初始化。”

值得注意的是,值初始化不是原始C ++ 98的一部分。 它是在C ++ 03中由Andrew Koenig(“Koenig查找”成名)引入的,以便處理純默認初始化的意外影響的一些嚴重問題。 這是()初始化程序在C ++ 98中為您購買的內容。

編輯我的原始答案是非常錯誤的,所以我對其進行了大量編輯。

如果你想保證在沒有值初始化調用的情況下A::a被零初始化,例如

A a1; //

要么

B() { .... }

那么你可以給A一個構造函數並在那里進行初始化:

class A {
public:
  A() : a() {} // value initialization of a, means zero initialization here.
    int a;
};

否則,在BC的構造函數中顯式調用A()會執行值初始化。

// value initialization of A sub-object leads to zero initialization of A::a
 B() : A() {} 

這也適用於A實例的初始化:

A a1 = A();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM