构造函数调用序列

时间:2017-01-01 10:37:39

标签: c++

示例1:

"language": {
            "infoFiltered":"",
            "processing": "<img src='~/Content/images/loadingNew.gif' />"
        },

输出:

#include <iostream>

class A
{
public:
    A(int a)
    {
        std::cout << "A: " << a << '\n';
    }

      A()
    {
        std::cout << "A" <<'\n';
    }
};

class B: public A
{
    private:
    int b;
    A a1;
public:
    B(int a, double b)
    : a1(a)
    {
        std::cout << "B: " << b << '\n';
    }

};

class C: public B
{
public:
    C(int a , double b , char c)
    : B(a, b)
    {
        std::cout << "C: " << c << '\n';
    }
};

int main()
{
    C c(5, 4.3, 'R');

    return 0;
}

示例2:

A
A: 5
B: 4.3
C: R

输出:

#include <iostream>

class A
{
public:
    A(int a)
    {
        std::cout << "A: " << a << '\n';
    }

      A()
    {
        std::cout << "A: " <<'\n';
    }
};

class B: public A
{
    private:
    int b;
    A a1;
public:
    B(int a, double b)
    : A(a)
    {
        std::cout << "B: " << b << '\n';
    }

};

class C: public B
{
public:
    C(int a , double b , char c)
    : B(a, b)
    {
        std::cout << "C: " << c << '\n';
    }
};

int main()
{
    C c(5, 4.3, 'R');

    return 0;
}

我从CPP中理解的是,首先调用基类的构造函数然后初始化成员,最后调用派生类的构造函数。那么为什么我没有得到输出的前2行相同?

1 个答案:

答案 0 :(得分:3)

为什么你会期望它们是一样的?在你的第一个例子中这个片段:

ods html

它首先隐式初始化基类(使用默认构造函数),它向终端输出单B(int a, double b) : a1(a) ,然后初始化成员变量A,输出a1。您的代码实际上等同于:

A: 5

第二个例子完全颠倒了:

B(int a, double b)
: A(), // implicit
  b(), // implicit
  a1(a)

使用单个参数构造函数(输出B(int a, double b) : A(a) )显式初始化base,然后使用默认构造函数(outputs A: 5)隐式初始化成员变量。此代码等同于:

A

是否在构造函数中放置显式初始化代码并不重要 - 首先初始化 ALL 基类,然后初始化 ALL 成员变量。这些初始化要么使用您给出的参数,要么在省略它们时默认初始化。如果省略初始化程序并且没有可用的默认构造函数,则编译将失败并显示错误。