繁体   English   中英

继承,为什么要为基类C ++调用两个构造函数

[英]Inheritance, why do two constructors get called for base class, C++

我正在尝试在我的书中做作业,但我不理解输出结果。 当程序中的主代码运行时,输出为:

B :: B(3)

B :: B()//为什么输出

B :: B(-3)

D :: D(3)

它得到这个从调用B::B(int n) {}第一,然后B::B() {}随后在接下来的两行,我得到的。 因此,该程序称为第一个程序,因为它在函数中被声明为构造函数A类,并且它必须分配值,我没有得到的是输出线2,为什么甚至调用B::B() {} 它被称为构造函数,但不应仅调用带有参数的构造函数?

class B {
public:
    B(); //why is this  called?
    B(int n);
};

// Definitions of B
B::B() { 
    cout << "B::B()\n";
}
B::B(int n) {
    cout << "B::B(" << n << ")\n";
}

class D : public B {
public:
    D();
    D(int n);
private:
    B b;
};

// Definitions of D
D::D() {
    cout << "D::D()\n";
}
D::D(int n) : B(n) {
    b = B(-n);
    cout << "D::D("<< n <<")\n";
}

int main(int argc, const char * argv[]) {
    // insert code here...

    D d(3);
    return 0;    
}

首先,将基类构造函数称为: B::B(3)
然后, b字段的构造函数称为: B::B()
然后执行派生的构造函数主体( 构造完所有字段之后 )。
D的构造函数首先在b = B(-n);行上构造另一个B b = B(-n); (因此会打印B::B(-3) ),然后打印D::D(3)

您的D类包含两个B型对象。

  1. 继承的隐式B
  2. 名为b的显式B成员

您可以重写构造函数

D::D(int n) : B(n)
{
    b = B(-n);
    cout << "D::D("<< n <<")\n";
}

喜欢

D::D(int n) : B(n), b()
{
    b = B(-n);
    cout << "D::D("<< n <<")\n";
}

很明显B::B()来自何处。 因此,您的输出很容易解释:

B::B(3) // base constructor of `D`
B::B() // default construction of `b` member
B::B(-3) // explicit construction inside D::D(int)
D::D(3) // D::D(int)

如果你写

D::D(int n) : B(n), b(-n)
{
    cout << "D::D("<< n <<")\n";
}

相反,只有

B::B(3)
B::B(-3)
D::D(3)

剩下。

发表评论:

想象一下D看起来像:

class D : public B
{
public:
  D(int);
};

与构造函数定义

D::D(int v) { std::cout << "foo with " << v; }

然后,代码

D d(3);

版画

B::B()
foo with 3

只要B是默认可构造变量,它就完全有效。

如果B缺少默认的构造函数,则会出现编译器错误,并且希望将D的定义重写为

D::D(int v) : B(3) { std::cout << "foo with " << v; }

每个属于构造函数初始值设定项列表的直接基类或成员都是默认构造的(对于类类型)或对于基本类型的未初始化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM