为什么下面的代码:
#include <iostream>
using namespace std;
class A {
public:
A() {cout << "A constructor\n";}
~A() {cout << "A deconstructor\n";}
};
class B : public A {
public:
B() {cout << "B constructor\n";}
~B() {cout << "B deconstructor\n";}
};
class C : public B {
public:
C() {cout << "C constructor\n";}
~C() {cout << "C deconstructor\n";}
};
int main() {
A a = C();
cout << "Exiting scope of main!" << endl;
}产出如下:
A constructor
B constructor
C constructor
C deconstructor
B deconstructor
A deconstructor
Exiting scope of main!
A deconstructor注意:如果将main中的第一行替换为A* a = new C();,输出将如预期的那样:
A constructor
B constructor
C constructor
Exiting scope of main!预期的行为是在初始化A时调用构造函数a、B和C,只有在退出作用域后才调用解构函数。
发布于 2022-11-06 13:19:09
A a = C();是复制初始化,这意味着对象a是作为表达式C()的副本创建的。现在,复制构造函数A::A(const A&)需要一个A类型的参数,因为它有一个const A&类型的参数。
这反过来意味着右边的表达式必须以某种方式转换为A。这种隐式转换是可能的,因为C是B的基础,而后者又是A的基础。也就是说,可以隐式地将C对象转换为A。
最后,转换的结果将是一个A对象,该对象将用于复制初始化 a。
您可以通过为类A添加一个复制构造函数来确认这一点,如下所示。此外,由于破坏的顺序是相反的建设秩序,我们将得到输出显示在您的程序。特别是构造的顺序是A > B > C,因此,在完全表达式 A a = C();的末端,我们得到了与C < B < A相反的析构函数调用。
最后,当main作用域退出时,对对象a进行析构,然后得到该对象的析构函数调用。
class A {
public:
A() {cout << "A constructor " << this << " " << "\n";}
~A() {cout << "A deconstructor " << this << " " << "\n";}
A(const A&arg){cout << "A copy constructor " << this << " " << &arg << " " << "\n";}
};
class B : public A {
public:
B() {cout << "B constructor " << this << " " << "\n";}
~B() {cout << "B deconstructor " << this << " " << "\n";}
};
class C : public B {
public:
C() {cout << "C constructor " << this << " " << "\n";}
~C() {cout << "C deconstructor " << this << " " << "\n";}
};
int main() {
A a = C();
cout << "Exiting scope of main!" << endl;
}上述程序的输出如下:
A constructor 0x7ffec7a013b7 //A object is created first
B constructor 0x7ffec7a013b7 //next B object is created
C constructor 0x7ffec7a013b7 //third C object is created
A copy constructor 0x7ffec7a013b6 0x7ffec7a013b7 //the A object created at the beginning is used here
C deconstructor 0x7ffec7a013b7 //at end of full expression C is destroyed first
B deconstructor 0x7ffec7a013b7 //then B is destroyed
A deconstructor 0x7ffec7a013b7 //finally A is destroyed last as it was created first
Exiting scope of main!
A deconstructor 0x7ffec7a013b6 //at main exit the only remaining object a is destroyedhttps://stackoverflow.com/questions/74336001
复制相似问题