簡體   English   中英

C ++中的繼承構造函數

[英]Inherited Constructors in C++

我正在嘗試用C ++實踐繼承構造函數 我已經編譯並在gcc中運行以下程序,它運行正常。

#include<iostream>
using namespace std;

class Base1
{
public:
        Base1()
        {
                cout<<"Base1 Default Constructor\n";
        }
        Base1(int i)
        {
                cout<<"Base1 parametrized Constructor\n";
        }
};

class Base2
{
public:
        Base2()
        {
                cout<<"Base2 Default Constructor\n";
        }
        Base2(const string& s)
        {
                cout<<"Base2 parametrized Constructor\n";
        }
};

class Derived :public Base1, public Base2
{
public:
        using Base1::Base1;
        using Base2::Base2;
};

int main()
{
        Derived d1(3);        // OK 
        Derived d2("hello");  // OK 
}

輸出:

Base1 parametrized Constructor
Base2 Default Constructor
Base1 Default Constructor
Base2 parametrized Constructor

但是,我想知道, 為什么默認構造函數被調用?

正在調用默認構造函數,因為Derived繼承自Base1Base2 構造Derived對象時,需要構造這兩個基礎。 所以,當你這樣做

Derived d1(3);

你調用Base1(int i) 現在您需要構建Base2部分,因為您沒有指定方式,編譯器默認構造它。 同樣的事情發生在

Derived d2("hello");

由於您沒有指定如何在構造函數中構造Base1部件,因此編譯器默認為您構造它。 然后調用Base2(const string& s)來構造Base2部分。

基本上你擁有的是什么

class Derived :public Base1, public Base2
{
public:
        Derived(int n) : Base1(n), Base2() {}
        Derived(const std::string& str) : Base1(), Base2(str) {}
};

來自cppreference http://en.cppreference.com/w/cpp/language/using_declaration
如果using-declaration引用了正在定義的類的直接基類的構造函數(例如,使用Base :: Base;),則根據以下規則繼承該基類的構造函數:

1)一組候選繼承構造函數由
a)基類的所有非模板構造函數(省略省略號參數后,如果有的話)(自C ++ 14起)
b)對於具有默認參數或省略號參數的每個構造函數,通過刪除省略號並從參數列表的末尾逐個省略默認參數形成的所有構造函數簽名
c)基類的所有構造函數模板(省略省略號參數后,如果有的話)(自C ++ 14起)
d)對於具有默認參數或省略號的每個構造函數模板,通過刪除省略號並從參數列表的末尾逐個省略默認參數形成的所有構造函數簽名
2)所有候選繼承的構造函數都不是默認構造函數或復制/移動構造函數,並且其簽名與派生類中的用戶定義構造函數不匹配,在派生類中隱式聲明。 默認參數不會被繼承:

struct B1 {
    B1(int);
};
struct D1 : B1 {
    using B1::B1;
// The set of candidate inherited constructors is 
// 1. B1(const B1&)
// 2. B1(B1&&)
// 3. B1(int)

// D1 has the following constructors:
// 1. D1()
// 2. D1(const D1&) 
// 3. D1(D1&&)
// 4. D1(int) <- inherited
};

struct B2 {
    B2(int = 13, int = 42);
};
struct D2 : B2 {
    using B2::B2;
// The set of candidate inherited constructors is
// 1. B2(const B2&)
// 2. B2(B2&&)
// 3. B2(int = 13, int = 42)
// 4. B2(int = 13)
// 5. B2()

// D2 has the following constructors:
// 1. D2()
// 2. D2(const D2&)
// 3. D2(D2&&)
// 4. D2(int, int) <- inherited
// 5. D2(int) <- inherited
};

繼承的構造函數等效於用戶定義的構造函數,它們具有空主體,並且具有由單個嵌套名稱說明符組成的成員初始化程序列表,該列表將所有參數轉發給基類構造函數。

它具有與相應基礎構造函數相同的訪問權限。 如果用戶定義的構造函數滿足constexpr構造函數要求,那就是constexpr。 如果刪除相應的基本構造函數或者刪除默認的默認構造函數,則刪除它(除了構造函數被繼承的基礎的構造不計算)。 繼承構造函數無法顯式實例化或顯式專用。

如果兩個using-declarations繼承具有相同簽名的構造函數(來自兩個直接基類),則該程序格式錯誤。

暫無
暫無

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

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