内部类析构函数在基类析构函数之后调用

Inner class destructor is called after Base class destructor

本文关键字:析构函数 调用 之后 内部类 基类      更新时间:2023-10-16

我有一个基本而简单的问题。

我有这种情况:

#include <iostream>
using namespace std;
class Inner1
{
public:
    ~Inner1() {cout << "Inner1 Desn";};
};
class Inner2
{
public:
    ~Inner2() {cout << "Inner2 Desn";};
};
class Base
{
public:
    ~Base() {cout << "Base Desn";};
    Inner1 inner1;
    Inner2 inner2;
};
int main() {
    Base base;
    return 0;
}

我的控制台现在告诉我:

称为
基本析构函数 调用
的 Inner2 析构函数 调用的 Inner1 析构函数

这是正常行为吗?因为某些功能
的功能在我的基类析构函数中已经销毁,内部类依赖于在他们身上。

不建议的解决方法:

只需添加一个"Destroyer"类,对象位于第一个位置:

[...]
class Base
    {
    public:
        ~Base() {cout << "Base Desn";};
        class Destroyer
        {
             ~Destroyer()
             {
                 //Put the stuff here because this destr will be called last
                 cout << "Destroyer Desn";
             }
        } _destroyer;
        Inner1 inner1;
[...]

谢谢你的帮助

这是正常行为吗?

是的。子对象析构函数由容器类的析构函数调用。特别是,子对象将在执行容器类析构函数的主体后销毁。

因为某些功能的功能 在我的基类析构函数中已经销毁,内部类依赖于它们。

只有当内部类 [sic] 析构函数依赖于包含它们的 Base 实例时,这才是一个问题。在这种情况下,Base不应将它们作为成员包含,或者它们的析构函数不应依赖于Base

使用此代码:

#include <iostream>
class Base
{
    public:
        class Sub1
        {
            public:
                Sub1()
                {
                    std::cout << "Base::Sub1::Constructedn";
                }
                ~Sub1()
                {
                    std::cout << "Base::Sub1::Destroyedn";
                }
        };
        class Sub2
        {
            public:
                Sub2()
                {
                    std::cout << "Base::Sub2::Constructedn";
                }
                ~Sub2()
                {
                    std::cout << "Base::Sub2::Destroyedn";
                }
        };

        Sub1    sub1;
        Sub2    sub2;
        Base()
        {
            std::cout << "Base::Constructedn";
        }
        ~Base()
        {
            std::cout << "Base::Destroyedn";
        }
};
int main()
{
    Base    base;
}

我得到(手动添加评论)

> ./a.out
// Build all members first in the order they are declared.
Base::Sub1::Constructed
Base::Sub2::Constructed
// Call the constructor of the object
Base::Constructed
// Destruction happens in revers.
// Calls the destructor code to handle all local resources
Base::Destroyed
// Then destroy all members in reverse order of declaration
Base::Sub2::Destroyed
Base::Sub1::Destroyed

类成员是按照它们在类中定义的顺序构造的。这意味着,

class Demonstration
{
    XClass x;
    YClass y;
};

在上面的例子中,x将在y之前构造。由于销毁以与构造相反的顺序发生,因此y总是在x之前被销毁。