2017-03-17 147 views
2

我正在尝试使用C++继承构造函数。我编译并在gcc中运行以下程序,并且工作正常。C++中的继承构造函数

#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 

但是,我想知道,为什么叫默认构造函数?

回答

5

默认构造函数被调用,因为Derived继承自Base1Base2。当你构造一个对象时,这两个基地都需要构建。所以,当你做

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) {} 
}; 
1

从cppreference http://en.cppreference.com/w/cpp/language/using_declaration
如果使用声明指所定义的类的直接基的构造(例如,使用基本::基地),构造根据以下规则继承该基类:

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。如果删除相应的基础构造函数或者删除默认的默认构造函数(除了构造函数被继承的基础的构造不计算在外),它将被删除。继承构造函数不能显式实例化或明确专用。

如果两个使用声明继承具有相同签名的构造函数(来自两个直接基类),则该程序不合格。