-
梵蒂冈之花
如果基类构造函数没有参数,则会自动调用它们。如果要调用带有参数的超类构造函数,则必须使用子类的构造函数初始化列表。与Java不同,C+支持多重继承(无论是好是坏),因此基类必须按名称引用,而不是“Super()”。class SuperClass{
public:
SuperClass(int foo)
{
// do something with foo
}};class SubClass : public SuperClass{
public:
SubClass(int foo, int bar)
: SuperClass(foo) // Call the superclass constructor in the subclass' initialization list.
{
// do something with bar
}};构造函数初始化列表的更多信息这里和这里.
-
月关宝盒
在C+中,在输入构造函数之前,将为您调用所有超类和成员变量的无参数构造函数。如果要传递参数,则有一个单独的语法,称为“构造器链接”,如下所示:class Sub : public Base{
Sub(int x, int y)
: Base(x), member(y)
{
}
Type member;};如果在此点运行任何内容,则调用以前已完成构造的基/成员的析构函数,并将异常重新抛出给调用方。如果要在链接期间捕获异常,则必须使用函数try块:class Sub : public Base{
Sub(int x, int y)
try : Base(x), member(y)
{
// function body goes here
} catch(const ExceptionType &e) {
throw kaboom();
}
Type member;};在这种形式中,请注意try块是函数的主体,而不是在函数的主体内;这允许它捕获隐式或显式成员和基类初始化引发的异常,以及在函数正文期间抛出的异常。但是,如果函数CATCH块不抛出不同的异常,运行库将重新抛出原始错误;初始化期间出现异常。不可能被忽视。
-
胡说叔叔
在C+中,有一个构造函数初始化列表的概念,它是您可以并且应该调用基类构造函数的地方,也是您应该初始化数据成员的地方。初始化列表在冒号后面的构造函数签名之后,在构造函数主体之前。假设我们有一个A班:class A : public B{public:
A(int a, int b, int c);private:
int b_, c_;};然后,假设B有一个接受int的构造函数,A的构造函数可能如下所示:A::A(int a, int b, int c)
: B(a), b_(b), c_(c) // initialization list{
// do something}如您所见,基类的构造函数在初始化列表中调用。顺便说一下,初始化列表中的数据成员比在构造函数主体内分配b_和c_值更好,因为这样可以节省额外的赋值成本。请记住,数据成员总是按照类定义中声明的顺序进行初始化,而不管它们在初始化列表中的顺序如何。为了避免出现奇怪的错误,如果数据成员相互依赖,则应该始终确保成员的顺序在初始化列表和类定义中是相同的。出于同样的原因,基类构造函数必须是初始化列表中的第一项。如果完全忽略它,则将自动调用基类的默认构造函数。在这种情况下,如果基类没有默认构造函数,则会得到编译器错误。