我如何调用基类的构造函数?

我花了很多Java编程。 在那里你调用你从super();inheritance的类super(); (你们大概都知道)

现在我有一个C ++类,它有一个默认的构造函数,它需要一些参数。 例:

 class BaseClass { public: BaseClass(char *name); .... 

如果我inheritance这个类,它给了我警告,没有适当的默认构造函数可用。 那么在C ++中是否有像super()这样的东西,还是我必须定义一个函数来初始化所有variables?

您可以在子类的构造函数的初始化程序列表中执行此操作。

 class Foo : public BaseClass { public: Foo() : BaseClass("asdf") {} }; 

带有参数的基类构造函数必须在任何成员初始化之前调用。

在头文件中定义一个基类:

 class BaseClass { public: BaseClass(params); }; 

然后将派生类定义为inheritanceBaseClass:

 class DerivedClass : public BaseClass { public: DerivedClass(params); }; 

在源文件中定义BaseClass构造函数:

 BaseClass::BaseClass(params) { //Perform BaseClass initialization } 

默认情况下,派生构造函数只调用没有参数的默认基类构造函数; 所以在这个例子中,当调用派生构造函数时不会自动调用基类构造函数,但可以通过在冒号(:)后面添加基类构造函数语法来实现。 定义一个自动调用其基础构造函数的派生构造函数:

 DerivedClass::DerivedClass(params) : BaseClass(params) { //This occurs AFTER BaseClass(params) is called first and can //perform additional initialization for the derived class } 

BaseClass构造函数在DerivedClass构造函数之前DerivedClass ,如果需要,可以将相同/不同的参数params传递给基类。 这可以嵌套到更深的派生类。 派生的构造函数必须调用EXACTLY ONE基础构造函数。 析构函数是AUTOMATICALLY调用构造函数被调用的REVERSE顺序。

编辑:如果您从任何virtual类inheritance,通常要实现多重inheritance钻石inheritance有此规则的例外。 那么你必须明确地调用所有virtual基类的基础构造函数,并明确地传递参数,否则将只调用它们的默认构造函数而不带任何参数。 请参阅: 虚拟inheritance – 跳过构造函数

你必须使用启动器:

 class DerivedClass : public BaseClass { public: DerivedClass() : BaseClass(<insert arguments here>) { } }; 

这也是你如何构build你的类没有构造函数(或者你想要初始化)的成员。 任何未提及的成员将被默认初始化。 例如:

 class DerivedClass : public BaseClass { public: DerivedClass() : BaseClass(<insert arguments here>) , nc(<insert arguments here>) //di will be default initialized. { } private: NeedsConstructor nc; CanBeDefaultInit di; }; 

成员指定的顺序是不相关的(虽然构造函数必须先来),但是它们将被构造的顺序是以声明顺序。 所以nc总是会在di之前被构造的。

关于超级的select; 在大多数情况下,您可以在派生类的初始化列表中使用基类,或者在其他地方进行工作时使用Base::someData语法,派生类重新定义数据成员。

 struct Base { Base(char* name) { } virtual ~Base(); int d; }; struct Derived : Base { Derived() : Base("someString") { } int d; void foo() { d = Base::d; } }; 

在C ++中没有super()。 您必须明确地通过名称调用基础构造函数。

在初始化程序列表中使用基类的名称。 初始化程序列表出现在方法主体之前的构造函数签名之后,可用于初始化基类和成员。

 class Base { public: Base(char* name) { // ... } }; class Derived : Base { public: Derived() : Base("hello") { // ... } }; 

或者,一些人使用的模式是自己定义“超级”或“基础”。 也许一些赞成这种技术的人是转向C ++的Java开发人员。

 class Derived : Base { public: typedef Base super; Derived() : super("hello") { // ... } };