C++ C++;继承初始值设定项列表

C++ C++;继承初始值设定项列表,c++,inheritance,C++,Inheritance,我对C++非常陌生,但我来自Java背景,因此我了解大多数OOP概念。我正在阅读一本介绍性指南,遇到了以下示例: [Foo.H] class A { public: A(int something); }; class B : public A { public: B(int something); }; [Foo.C] #include "Foo.H" A::A(int something) { printf("Something

我对
C++
非常陌生,但我来自
Java
背景,因此我了解大多数
OOP
概念。我正在阅读一本介绍性指南,遇到了以下示例:

[Foo.H] 
class A
{
    public:
       A(int something);
};

class B : public A
{
    public:
       B(int something);
};

[Foo.C] 
#include "Foo.H"

A::A(int something)
{
    printf("Something = %d\n", something);
}

B::B(int something) : A(something)
{
}
假设通过将
A(something)
传递到
B::B(int something)
的初始值设定项列表,它将执行
A::A(int something)
的代码,这是否正确?另外,为什么我只调用
A(something)
,而不是从initializer列表中调用
A::A(something)

基本上,我是在问:以上是否等同于:

B::B(int something)
{
    A::A(something)
}
让我解释一下为什么我感到困惑

如果我使用:

B::B(int something) : A(something)
{
    int x = 5;
    printf("x = %d", x);
}
并通过

B::B(7);
这会先打印出
x=5
还是
something=7
?为什么要按这个顺序执行呢

我只是对语法有点困惑,这使得即使在这个简单的例子中也很难理解和可视化发生的继承。

是的,
a(something)
传递该值很像
super
。您不必使用
A::A
,因为该语言会自动将基类名称注入子类

然而,它并不等同于

B::B(int something)
{
    A::A(something)
}
因为那不是法律法规。您只能在初始值设定项列表中选择要调用的父构造函数


至于你关于印刷的问题……你试过了吗?您将看到父级
something=
首先打印,然后是
x=

不,它们不是等价的

子类的构造函数将调用其父类的默认构造函数,除非在初始值设定项列表中明确告诉它

B::B(int something){}
将隐式调用
A::A()
,如果
A
没有默认构造函数,它将不会编译

B::B(int something)
{
    A::A(something)
}
这是因为它尝试在初始值设定项列表中隐式调用
A::A()
,然后调用
A::A(某物)
,正如您所知,如果
A
没有默认构造函数,它将不会编译

因此,如果您想调用不同的父构造函数,唯一的方法就是在初始值设定项列表中调用

B::B(int something) : A(something) {}
这是B的构造函数。构造函数所做的第一件事是构造它的基类(按照类中声明的顺序,而不是按照构造函数的顺序),然后构造成员对象(按照类中声明的顺序,而不是按照构造函数的顺序),然后执行主体(
{}
中的代码). 它这样做的原因是因为a
B
是一个
a
对象,所以它必须是一个完整的
a
,才能成为
B
对象。在执行任何成员函数的代码之前,必须完全构造所有成员,否则可能会发生不好的事情。因此,必须先构造基类和成员,然后才能开始构造函数体

如果要更改基类或成员的初始化方式(例如传递整数而不是默认构造),可以将其放入初始值设定项列表中:

B::B(int something) : A(something)
{
    int x = 5;
    printf("x = %d", x);
}
您不必限定
A
的构造函数的名称,因为我们已经在对象
B
的上下文中,并且
B
已经知道
A

B::B(int something)
{
    A::A(something)
}
此代码无效,因为在执行
{}
中的主体之前,
B
将构造它的
A
对象。由于已经构造了
A
,因此在主体中调用
A::A
毫无意义,编译器将对此进行诊断

B::B(int something) : A(something)
{
    int x = 5;
    printf("x = %d", x);
}
如前所述,在构造B时,它首先构造基类,然后构造成员,然后执行主体。所以你会看到

something = 7
x = 5

我没有一个C++编译器当前可用。我只是在读一些基本的文学作品。感谢您的简短但包罗万象的解释!通常认为等待24小时将答案标记为已接受是礼貌的,给人们时间查看并正确回答
something = 7
x = 5