latley我在Java中花了很多编程。在那里,您使用super();
调用您继承的类(您可能都知道)
现在我有一个C ++类,它有一个带有一些参数的默认构造函数。例如:
class BaseClass {
public:
BaseClass(char *name); ....
如果我继承了类,它会给我警告,没有合适的默认构造函数可用。那么在C ++中有类似super()
的东西,还是我必须定义一个初始化所有变量的函数?
答案 0 :(得分:80)
您可以在子类构造函数的初始化列表中执行此操作。
class Foo : public BaseClass {
public:
Foo() : BaseClass("asdf") {}
};
在初始化任何成员之前,必须在那里调用带参数的基类构造函数。
答案 1 :(得分:27)
在头文件中定义一个基类:
class BaseClass {
public:
BaseClass(params);
};
然后将派生类定义为继承BaseClass:
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
构造函数之前调用,如果需要,可以将相同/不同的参数params
转发到基类。这可以嵌套用于更深层次的派生类。派生的构造函数必须调用EXACTLY ONE基础构造函数。析构函数在REVERSE命令中被AUTOMATICALLY调用,调用构造函数。
编辑:如果您继承任何virtual
类,通常是为了实现多重继承或钻石继承,则此规则有一个例外。然后你必须显式调用所有virtual
基类的基础构造函数并显式传递参数,否则它只会调用默认构造函数而不用任何参数。请参阅:virtual inheritance - skipping constructors
答案 2 :(得分:17)
你必须使用initiailzers:
class DerivedClass : public BaseClass
{
public:
DerivedClass()
: BaseClass(<insert arguments here>)
{
}
};
这也是你如何构造没有构造函数(或者你想要初始化)的类的成员。未提及的任何成员将被默认初始化。例如:
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
之前构建。
答案 3 :(得分:4)
关于super的替代方案;在大多数情况下,您可以在派生类的初始化列表中使用基类,或者在其他地方工作时使用Base::someData
语法,派生类重新定义数据成员。
struct Base
{
Base(char* name) { }
virtual ~Base();
int d;
};
struct Derived : Base
{
Derived() : Base("someString") { }
int d;
void foo() { d = Base::d; }
};
答案 4 :(得分:3)
在初始化列表中使用基类的名称。初始化列表出现在方法体之前的构造函数签名之后,可用于初始化基类和成员。
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")
{
// ...
}
};
答案 5 :(得分:2)
C ++中没有super()。您必须按名称显式调用Base Constructor。