我正在尝试在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
但是,我想知道,为什么要调用默认构造函数?
答案 0 :(得分:5)
正在调用默认构造函数,因为Derived
继承自Base1
和Base2
。构造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) {}
};
答案 1 :(得分:2)
来自cppreference http://en.cppreference.com/w/cpp/language/using_declaration
如果using-declaration引用了正在定义的类的直接基类的构造函数(例如,使用Base :: Base;),则根据以下规则继承该基类的构造函数:
1)一组候选继承构造函数由
组成
a)基类的所有非模板构造函数(省略省略号参数后,如果有的话)(自C ++ 14起)
b)对于具有默认参数或省略号参数的每个构造函数,通过删除省略号并从参数列表的末尾逐个省略默认参数形成的所有构造函数签名逐一
c)基类的所有构造函数模板(省略省略号参数后,如果有的话)(自C ++ 14起)
d)对于具有默认参数或省略号的每个构造函数模板,通过删除省略号并从参数列表的末尾逐个省略默认参数形成的所有构造函数签名逐一
2)所有候选继承的构造函数都不是默认构造函数或复制/移动构造函数,并且其签名与派生类中的用户定义构造函数不匹配,在派生类中隐式声明。默认参数不会被继承:
$("#myButton").val($("#myButton").val() === "Hide table" ? "Show table" : "Hide table");
继承的构造函数等效于用户定义的构造函数,它们具有一个空体,并且具有一个成员初始化列表,该列表由一个嵌套名称说明符组成,它将所有参数转发给基类构造函数。
它具有与相应基础构造函数相同的访问权限。如果用户定义的构造函数满足constexpr构造函数要求,那就是constexpr。如果删除相应的基本构造函数或者删除默认的默认构造函数,则删除它(除了构造函数被继承的基础的构造不计算)。继承构造函数不能显式实例化或显式专门化。
如果两个using-declarations继承具有相同签名的构造函数(来自两个直接基类),则该程序格式错误。