当 “B c = a” 时,为什么输出不是 : “cosntructor A\n 构造函数 B\n 复制构造函数 B”?

when "B c = a" why the output isnt : "cosntructor A\n constructor B\n copy constructor B"?

提问人: 提问时间:4/4/2022 最后编辑:Yksisarvinen 更新时间:4/4/2022 访问量:87

问:

输出:

当为什么输出不是:B c = a

cosntructor A
constructor B
copy constructor B

而不是

cosntructor A
copy constructor B

?

======================================================================================== 法典

class A {

public:
    A(const A&);
    A();
    ~A();
};

class B : public A {
public:
    B(string, int, float, int);
    B(const B&);
    B();
    ~B();
};

A::A() { cout << "constructor A\n"; }
A::A(const A& old_str) { cout << "copy constructor A\n"; }
A::~A() { cout << "destructor A\n"; }

B::B() { cout << "constructor B\n"; }
B::B(const B& old_str) { cout << "copy constructor B\n"; }
B::~B() { cout << "destructor B\n"; }

int main()
{
    B a;
    cout << "\n\n\n";
    B c = a;
    cout << "\n\n\n";
}

我不明白 c 的“B c = a”何时同时被称为 A 和 B 的构造函数。对于 B c,输出是构造函数 A 构造函数 B,这很好,为什么“B c = a”没有发生同样的情况

C++ 继承 析构函数 复制构造函数

评论

0赞 François Andrieux 4/4/2022
不要用单引号分隔每行,而是在每行代码前添加 4 个空格字符以形成单个代码块。
2赞 j6t 4/4/2022
在行中只构造一个对象 () 没有理由期望调用两个构造函数。cB c = a;
1赞 Caleth 4/4/2022
@j6t 的 base-subobject 是默认构造的。Ac
1赞 Drew Dormann 4/4/2022
“为什么输出不是......”形式的问题可能应该包括一些解释,说明为什么你认为输出应该这样。你正在做一些不正确的假设,但我们必须猜测这些不正确的假设是什么。
1赞 molbdnilo 4/4/2022
同样的情况发生了 - 首先构造子对象,然后构造零件(通过复制)。 不是首先默认构造然后复制到。ABac

答:

0赞 user12002570 4/4/2022 #1

当 B c = a 为什么输出不是 :

因为是复制初始化。意义是作为对象的副本创建的,使用复制构造函数。因此,由于语句,编译器隐式调用了复制构造函数。现在,在输入 的这个复制构造函数的主体之前,默认构造函数也被隐式调用。因此,你得到的输出是:B c = a;caB::B(const B&)B::B(const B&)B c = a;BA::A()

constructor A
copy constructor B.

另一方面,是默认初始化,它使用默认构造函数。因此,由于语句 .但是在输入这个默认构造函数的主体之前,默认构造函数也会被隐式调用。因此,你得到的输出是:B a;B::B()B::B()B a;BA::A()

constructor A
constructor B
1赞 Caleth 4/4/2022 #2

您不会看到打印的“复制构造函数 A”,因为您没有在复制构造函数中复制构造基。您可以在 member-initialiser-list 中执行此操作。AB

B::B(const B& other) : A(other) { cout << "copy constructor B\n"; }

现场观看

评论

0赞 user12002570 4/4/2022
这个答案是基于一个错误的假设。OP 从未问过为什么不打印“复制构造函数 A”。你看错了问题吗?OP询问为什么不打印“构造函数B”。
1赞 Vlad from Moscow 4/4/2022 #3

在此声明中

B c = a;

使用了由用户定义的类 B 的复制构造函数。

B::B(const B& old_str) { cout << "copy constructor B\n"; }

复制构造函数隐式调用基类 A 的默认构造函数来创建其基类子对象。因此,您拥有

cosntructor A
copy constructor B

事实上,类 B 的复制构造函数

B::B(const B& old_str) { cout << "copy constructor B\n"; }

相当于

B::B(const B& old_str) : A() { cout << "copy constructor B\n"; }

你感到困惑的原因是,你似乎认为在这个声明中

B c = a;

首先,使用类的默认构造函数创建对象,然后使用另一个构造函数将对象分配给创建的对象:复制构造函数。cBac

但是,只能使用一个构造函数来构造对象,在本例中,使用了类 B 的复制构造函数。

在此声明中

B c = a;

两者都没有分配。 是初始化所创建对象的初始值设定项。您也可以按以下方式重写此声明,使其更清晰ac

B c( a );