【问题标题】:Destructor called two times in C++在 C++ 中调用了两次析构函数
【发布时间】:2021-07-03 08:07:18
【问题描述】:

我有一个包含两个这样的类的代码:

A类:

class A {
    int a, b;
public:
    A(int x, int y) {
        a = x;
        b = y;
    }
    ~A() {
        cout << "Exit from A\n";
    }
    void values() {
        cout << a << "\n" << b << endl;
    }
};

B类:

class B :public A
{
    int c;
public:
    B(int x, int y, int z) :A(x, y)
    {
        c = z;
    }
    ~B() {
        cout << "Exit from B\n";
    }
    void values() {
        A::values();
        cout << c << endl;
    }
};

主要功能:

int main()
{
    A testA(1, 2);
    testA.values();
    B testB(10, 20, 30);
    testB.values();
}

这就是我得到的:

1
2
10
20
30
Exit from B
Exit from A
Exit from A

首先从 B 类调用析构函数,然后从 A 调用两次。为什么要两次?不知道怎么改。

【问题讨论】:

  • 你有两个对象,所以当然析构函数被调用了两次。每个对象一次。
  • @Devolus 但我有 1 个来自 A 类的对象,所以为什么这个类有两个析构函数
  • “我不知道如何改变它。” - 我不知道你为什么想要。你有两个对象,它们都是 A 的根(一个直接,一个通过继承),所以 A 为每个销毁打印一次。
  • B 是一个A,所以当你销毁一个B 时,你也在销毁一个A。这就是继承的工作原理
  • 每个B is-a A。如果你不想要这种行为,不要让B 继承自A,因为这有点继承的意义

标签: c++ class destructor


【解决方案1】:

maintestAtestBA 基础子对象中创建了2 个A 对象。两者都在 main 结束时销毁,与声明的顺序相反。

class A {
    int a, b;
    std::string msg;
protected:
    A(int x, int y, std::string m) : a(x), b(y), msg(m) {}
public:
    A(int x, int y) : A(x, y, "Exit from A\n") {}
    virtual ~A() {
        std::cout << msg;
    }
    virtual void values() {
        std::cout << a << "\n" << b << std::endl;
    }
};

class B :public A
{
    int c;
public:
    B(int x, int y, int z) : A(x, y, "Exit from B\n"), c(z) {}
    void values() override {
        A::values();
        std::cout << c << std::endl;
    }
};

【讨论】:

  • 我现在明白了,但是输出中是否有可能只从 A 退出一次?
  • 您从A 退出了两次。如果您想从A 退出一次,则只创建一个A。这就是我们都想说的。您的输出正确地描述了您的程序。如果你希望你的输出不同,你需要一个不同的程序来正确描述它。
  • @keyboardNoob 有很多方法可以做到这一点。您可以将cout &lt;&lt; "Exit from A\n"; 从析构函数移动到主函数。你可以添加一个成员来保存coutA的消息,并在B中将其设置为"Exit from B\n"。您可以在B 中删除来自A 的继承
【解决方案2】:

您有对象testA,它将从A (1) 调用它的析构函数。 您有 Object testB,它派生自 A,因此它将调用析构函数 B (1) 和析构函数 A (2)。

这正是你的输出所说的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-06
    • 2010-12-29
    • 1970-01-01
    • 1970-01-01
    • 2015-07-26
    • 2017-05-24
    • 1970-01-01
    相关资源
    最近更新 更多