是否必须在超类中具有默认构造函数才能继承它?假设每个派生类构造函数都显式调用超类构造函数之一,并提供正确的参数——这样的代码会起作用吗?
5 回答
是否必须在超类中具有默认构造函数才能继承它?
不。
如果基类中没有默认构造函数,则需要使用派生类构造函数的成员初始化列表中的参数显式调用基类构造函数。
例子,
class base
{
public:
base(std::string const & s, int n);
};
class derived : public base
{
anotherClass obj;
public:
derived() : base("string", 10), obj(100)
{ //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ member-initialization list
}
};
注意 的语法base("string", 10)
。它调用基类的构造函数,"string"
作为第一个参数和10
第二个参数传递。
还要注意obj(100)
初始化成员变量的类型anotherClass
:obj(10)
调用作为参数的构造anotherClass
函数int
。
前提是
- 默认构造函数没有被显式调用
- 所有子类在构造时调用带有参数的用户定义的超类构造函数
不必编写默认构造函数。
如果子类的每个构造函数都使用父类的显式构造函数,则父类不需要具有默认构造函数。
如果您有一个没有默认构造函数的类,那么每个人都必须在实例化时使用显式构造函数,对吗?这是同一个概念,如果所有的孩子都确保从不调用默认构造函数,那么就不需要实现它。
不,有一个可能的例外。通常,基类构造函数将由紧接其上方的派生类调用,使用该派生类提供的参数(如果有)。如果所有直接派生类都显式初始化基类,则不需要默认构造函数。
一个可能的例外是如果您从基类虚拟继承。在这种情况下,初始化基类的不是直接派生类,而是最派生类。并且根据您的类层次结构的组织方式,您可能不希望派生最多的类知道基类;对于大多数派生类来说,只知道它直接继承的类就足够了。(当然,这是一个理想的情况,但并非总是如此。)幸运的是,几乎每次发生这种情况时,基类都是没有数据的抽象类(因此具有默认构造函数)。但这是要记住的事情。
不,您不需要默认构造函数。以下编译和运行,有或没有私有默认构造函数。
class A {
public:
A(int i) {
m = i;
}
private:
A() { } // This line can be commented out. Included only to make point
int m;
};
class B : A {
public:
B(int i)
: A(i)
{
}
};
int main() {
B b(10);
}