首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++:解构函数在退出作用域之前被调用

C++:解构函数在退出作用域之前被调用
EN

Stack Overflow用户
提问于 2022-11-06 12:53:19
回答 1查看 38关注 0票数 0

为什么下面的代码:

代码语言:javascript
复制
#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;
}

产出如下:

代码语言:javascript
复制
A constructor
B constructor
C constructor
C deconstructor
B deconstructor
A deconstructor
Exiting scope of main!
A deconstructor

注意:如果将main中的第一行替换为A* a = new C();,输出将如预期的那样:

代码语言:javascript
复制
A constructor
B constructor
C constructor
Exiting scope of main!

预期的行为是在初始化A时调用构造函数a、B和C,只有在退出作用域后才调用解构函数。

EN

回答 1

Stack Overflow用户

发布于 2022-11-06 13:19:09

A a = C();复制初始化,这意味着对象a是作为表达式C()的副本创建的。现在,复制构造函数A::A(const A&)需要一个A类型的参数,因为它有一个const A&类型的参数。

这反过来意味着右边的表达式必须以某种方式转换为A。这种隐式转换是可能的,因为CB的基础,而后者又是A的基础。也就是说,可以隐式地将C对象转换为A

最后,转换的结果将是一个A对象,该对象将用于复制初始化 a

您可以通过为类A添加一个复制构造函数来确认这一点,如下所示。此外,由于破坏的顺序是相反的建设秩序,我们将得到输出显示在您的程序。特别是构造的顺序是A > B > C,因此,在完全表达式 A a = C();末端,我们得到了与C < B < A相反的析构函数调用。

最后,当main作用域退出时,对对象a进行析构,然后得到该对象的析构函数调用。

代码语言:javascript
复制
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;
}

上述程序的输出如下:

代码语言:javascript
复制
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 destroyed
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74336001

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档