C++ 如何调用基类构造函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6923722/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I call the base class constructor?
提问by Stefan
latley I spent much programming in Java. There you call the class you Inherited from with super();
(you all probably know that)
我花了很多时间用 Java 编程。在那里你称之为继承自的类super();
(你们可能都知道)
Now I have a class in C++ which has a default constructor which takes some arguments. Example:
现在我在 C++ 中有一个类,它有一个带有一些参数的默认构造函数。例子:
class BaseClass {
public:
BaseClass(char *name); ....
If I inherit the class it gives me the warning, that there is no appropriate default constructor available. So is there something like super()
in C++, or do I have to define a function where I initialize all variables?
如果我继承该类,它会给我警告,即没有合适的默认构造函数可用。那么super()
在 C++ 中是否有类似的东西,或者我是否必须定义一个函数来初始化所有变量?
回答by Bj?rn Pollex
You do this in the initializer-list of the constructor of the subclass.
您可以在子类的构造函数的初始化列表中执行此操作。
class Foo : public BaseClass {
public:
Foo() : BaseClass("asdf") {}
};
Base-class constructors that take arguments have to be called there before any members are initialized.
在初始化任何成员之前,必须在那里调用带有参数的基类构造函数。
回答by MasterHD
In the header file define a base class:
在头文件中定义一个基类:
class BaseClass {
public:
BaseClass(params);
};
Then define a derived class as inheriting the BaseClass:
然后将派生类定义为继承 BaseClass:
class DerivedClass : public BaseClass {
public:
DerivedClass(params);
};
In the source file define the BaseClass constructor:
在源文件中定义 BaseClass 构造函数:
BaseClass::BaseClass(params)
{
//Perform BaseClass initialization
}
By default the derived constructor only calls the default base constructor with no parameters; so in this example, the base class constructor is NOT called automatically when the derived constructor is called, but it can be achieved simply by adding the base class constructor syntax after a colon (:
). Define a derived constructor that automatically calls its base constructor:
默认情况下,派生构造函数只调用没有参数的默认基构造函数;所以在这个例子中,基类构造函数在派生构造函数被调用时不会自动调用,但可以通过在冒号 ( :
)后添加基类构造函数语法来实现。定义一个派生构造函数,自动调用其基构造函数:
DerivedClass::DerivedClass(params) : BaseClass(params)
{
//This occurs AFTER BaseClass(params) is called first and can
//perform additional initialization for the derived class
}
The BaseClass
constructor is called BEFORE the DerivedClass
constructor, and the same/different parameters params
may be forwarded to the base class if desired. This can be nested for deeper derived classes. The derived constructor must call EXACTLY ONE base constructor. The destructors are AUTOMATICALLY called in the REVERSE order that the constructors were called.
该BaseClass
构造被称为BEFOREDerivedClass
构造和相同/不同的参数params
,如果需要,也可以转发到的基类。这可以嵌套用于更深的派生类。派生构造函数必须只调用一个基构造函数。析构函数以调用构造函数的相反顺序自动调用。
EDIT: There is an exception to this rule if you are inheriting from any virtual
classes, typically to achieve multiple inheritanceor diamond inheritance. Then you MUST explicitly call the base constructors of all virtual
base classes and pass the parameters explicitly, otherwise it will only call their default constructors withoutany parameters. See: virtual inheritance - skipping constructors
编辑:如果您从任何virtual
类继承,则此规则有一个例外,通常是为了实现多重继承或菱形继承。那么你必须显式调用所有virtual
基类的基构造函数并显式传递参数,否则它只会调用它们的默认构造函数而没有任何参数。请参阅:虚拟继承 - 跳过构造函数
回答by Nicol Bolas
You have to use initiailzers:
您必须使用初始化程序:
class DerivedClass : public BaseClass
{
public:
DerivedClass()
: BaseClass(<insert arguments here>)
{
}
};
This is also how you construct members of your class that don't have constructors (or that you want to initialize). Any members not mentioned will be default initialized. For example:
这也是您构造没有构造函数(或您想要初始化)的类成员的方式。任何未提及的成员将被默认初始化。例如:
class DerivedClass : public BaseClass
{
public:
DerivedClass()
: BaseClass(<insert arguments here>)
, nc(<insert arguments here>)
//di will be default initialized.
{
}
private:
NeedsConstructor nc;
CanBeDefaultInit di;
};
The order the members are specified in is irrelevant (though the constructors must come first), but the order that they will be constructed in is in declaration order. So nc
will always be constructed before di
.
指定成员的顺序无关紧要(尽管构造函数必须在前),但它们的构造顺序是声明顺序。所以nc
总是会被构造之前di
。
回答by Seb Holzapfel
Regarding the alternative to super; you'd in most cases use use the base class either in the initialization list of the derived class, or using the Base::someData
syntax when you are doing work elsewhere and the derived class redefines data members.
关于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; }
};
回答by Scott Langham
Use the name of the base class in an initializer-list. The initializer-list appears after the constructor signature before the method body and can be used to initialize base classes and members.
在初始化列表中使用基类的名称。初始化列表出现在方法体之前的构造函数签名之后,可用于初始化基类和成员。
class Base
{
public:
Base(char* name)
{
// ...
}
};
class Derived : Base
{
public:
Derived()
: Base("hello")
{
// ...
}
};
Or, a pattern used by some people is to define 'super' or 'base' yourself. Perhaps some of the people who favour this technique are Java developers who are moving to C++.
或者,有些人使用的模式是自己定义“超级”或“基础”。也许一些喜欢这种技术的人是转向 C++ 的 Java 开发人员。
class Derived : Base
{
public:
typedef Base super;
Derived()
: super("hello")
{
// ...
}
};
回答by Shamim Hafiz
There is no super() in C++. You have to call the Base Constructor explicitly by name.
C++ 中没有 super() 。您必须按名称显式调用 Base Constructor。