c++ - 继承类中的构造函数调用

标签 c++ constructor initialization default default-constructor

考虑以下代码:

class A {
public:
    int a;
};

class B : public A {
public:
    B() { std::cout << "B[" << a << "]" << std::endl; }
};

class C : public B {
public:
    C() { std::cout << "C[" << a << "]" << std::endl; }
};

int main(int argc, char *argv[]) {

    B();
    std::cout << std::endl;
    C();

}

及其输出——用 g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 编译的程序:

B[0]

B[-2097962768]
C[-2097962768]

我发现获得第二个调用 -- C() -- 以初始化其值的唯一方法是添加对构造函数的显式调用,例如:

class B : public A {
public:
    B() : A() { std::cout << "B[" << a << "]" << std::endl; }
};

class C : public B {
public:
    C() : B() { std::cout << "C[" << a << "]" << std::endl; }
};

虽然我知道调用每个先前类的默认构造函数将初始化值,但在未指定任何内容时我无法看到正在调用的内容。

默认构造函数不是默认调用的——因此是它的句柄吗?

最佳答案

使用您的原始代码

class A {
public:
    int a;
};

class B : public A {
public:
    B() { std::cout << "B[" << a << "]" << std::endl; }
};

A 的成员没有被初始化,因为你没有指定任何初始化。通常,在 C++ 中,您不需要为不需要的东西付费。因此,默认情况下您不会为 POD 成员获取初始化(但是,您确实为具有构造函数的成员获取了初始化,因为其中指定了初始化)。

在您随后的“显式构造函数调用”代码中

class B : public A {
public:
    B() : A() { std::cout << "B[" << a << "]" << std::endl; }
};

您已经指定了 A 基类子对象的值初始化。这实际上减少了零初始化。

一样的区别

A* p = new A;

对比

A* p = new A();

后者对对象进行值初始化。


标准语……

C++11 §8.5/10:
“An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.”

C++11 §8.5./7:
“To value-initialize an object of type T means:
— if T is a (possibly cv-qualified) class type (Clause 9) with a user-provided constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
— if T is a (possibly cv-qualified) non-union class type without a user-provided constructor, then the object is zero-initialized and, if T’s implicitly-declared default constructor is non-trivial, that constructor is called.
— if T is an array type, then each element is value-initialized;
— otherwise, the object is zero-initialized.
An object that is value-initialized is deemed to be constructed and thus subject to provisions of this International Standard applying to “constructed” objects, objects “for which the constructor has completed,” etc., even if no constructor is invoked for the object’s initialization.”

可能值得注意的是,值初始化并不是原始 C++98 的一部分。它是在 C++03 中由 Andrew Koenig(因“Koenig 查找”而闻名)引入的,目的是处理纯默认初始化的意外效果的一些严重问题。这就是 C++98 中 () 初始化器为您带来的东西。

关于c++ - 继承类中的构造函数调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15092931/

相关文章:

ios - 在自己的初始值内使用的 Swift 变量

C++ 错误 : "size" declared as function returning a function

c++ - 无序关联容器什么时候发生重新散列?

java - 构造函数与 setter 注入(inject)

JavaScript ES6 : Grouping methods in es6 classes?

android - 错误: The Constructor File(URI) is undefined

C++:const-从一个初始化函数初始化多个数据成员

c - 使用声明的变量初始化数组

Android NDK 加载库 ("KERNEL32.DLL")

c++ - 通过在 C++ 中删除 vector 中的 vector 来释放内存