本文介绍了为什么析构函数在C ++中运行两次?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在执行编程任务时,我似乎对基本的C ++概念感到困惑。我在程序中发现了该错误,原因是析构函数的运行次数超出了预期。这是一个代码示例,展示了我在做什么,直到最基本的要求。

While doing my programming assignments, I seem to be stumbling over basic C++ concepts. I found the bug in my program and it was caused by my destructor running more times than I expected. Here is a code sample demonstrating what I am doing wrong, down to the bare essentials.

#include <iostream>
using namespace std;

class A
{
public:
    A(int num)
    {
        number = num;
        cout << "A constructed with number " << number << ".\n";
    }
    ~A()
    {
        cout << "A destructed with number " << number << ".\n";
    }
private:
    int number;
};

class B
{
public:
    B(A pa)
        : a(pa)
    {
        cout << "B constructor run.\n";
    }
    ~B()
    {
        cout << "B destructor run.\n";
    }
private:
    A a;
};


int main()
{
    A foo(7);
    {
        B bar(foo);
    }
    //Pause the program.
    system("pause");
}

我希望发生的是 A foo(7 ); 在堆栈中为名为 foo A 对象分配空间,并调用构造函数,传递了 7 。它将 7 分配给 number 并打印输出,指示构造函数已运行。现在 B bar(foo); 在堆栈中为名为 bar的 B 对象分配空间。 并调用构造函数,并按值传递 foo ,这只是 int 。构造函数将传递给它的 A 参数分配给它自己的私有数据成员 a ,然后将输出打印到屏幕上。

What I expect to happen is A foo(7); allocates space on the stack for an A object named foo and call the constructor, passing 7. It assigns 7 to number and prints output indicating the the constructor ran. Now B bar(foo); allocates space on the stack for a B object named bar and calls the constructor, passing foo by value, which is just a container for an int. The constructor assigns the A parameter passed to it to it's own private data member a, and prints output to the screen.

现在,当 bar 超出大括号时,我希望 bar 的析构函数被调用,该析构函数将输出打印到屏幕上,然后调用其数据成员的析构函数,即 A a 。该析构函数将输出打印到屏幕上,并丢弃其中包含的 int数字

Now, when bar goes out of scope at the closing curly brace, I expect bar's destructor to be called, which prints output to the screen, then calls the destructor for its data members, namely A a. That destructor prints output to the screen, and discards the int number that it was containing.

我期望的是输出应为:

A constructed with number 7.
B constructor run.
B destructor run.
A destructed with number 7.
//Destructors should be called in the reverse order of their construction right?

实际输出:

A constructed with number 7.
B constructor run.
A destructed with number 7. //This is unexpected.
B destructor run.
A destructed with number 7.

是什么造成了额外的破坏?

What is causing that extra destruction?

推荐答案

显然,它来自成员数据A a;我怀疑您的疑问是,为什么不看到A的任何构造输出,因为它是使用A类的默认copy-ctor构造的,因此最好为A类添加一个copy-ctor,以便您可以看到构造

Obviously it comes from member data A a; of class B. I guess your doubt is that why not see any construct output from A, because it's constructed with default copy-ctor for class A, It's better to add one copy-ctor for class A, so that you will see the construct procedure.

A(const A& a)
{
     number = a.number;
     cout << "A copy-constructed with number " << number << ".\n";
}

这篇关于为什么析构函数在C ++中运行两次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 07:52