关于c ++:为什么我的析构函数被调用,我该如何修复它

Why is my destructor being called and how can I fix it

本问题已经有最佳答案,请猛点这里访问。

嘿,伙计们,我在C++程序中遇到了我的析构函数问题。当我运行这个程序并接受用户输入时,它突然调用了析构函数,甚至在CUT甚至可以在语句中打印之前。假设用户输入是一个,因为我设计的这部分代码只接受输入1。我认为在您离开作用域时会调用析构函数,所以我认为应该至少在if语句中的cout之后调用析构函数,我将在下面对其进行注释,以便于大家阅读。如果有人能解释我的错误并改正它,那就太好了!在我的脑子里

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <string>
#include <stdlib.h>
#include <time.h>

using namespace std;

class creature{
public:
    creature();//default constructor
    creature(int a);
    ~creature();//desconstructor
    string getName();//accessor for the name
    static int getNumObjects();
private:
    string name;
    int happy_level;
    static int count;
};

在我的实现文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include"creature.h"

int creature::count=0;//initialize static member variable

creature::creature(){//default constructor
    name="bob";
    ++numberobject;

    cout<<"The default constructor is being called"<<endl;
}

creature::creature(int a)
{
    if(a==1)
    {
        name="billybob";

    }


    else if(a==2)
    {
        name="bobbilly";

    }

    else if(a==3)
    {
        name="bobbertyo";
        happy_level=1;
    }
}

creature::~creature()
{
    cout<<"The destructor is now being called"<<endl;
    cout<<creature::getName()<<" is destroyed."<<endl;
     --count;
    cout<<"Now you have a total number of"<<creature::getNumObjects()<<" creature"<<endl;
}

在我的主班我有

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include"creature.h"

int main()
{

   creature foo;//this is where the default constructor gets called which is good
   int choice;

   cout<<"enter 1 2 or 3 to choose ur monster"<<endl;
   cin>>choice;

   foo=creature(choice);

   if(choice==1)
    {
        cout<<"hi"<<endl;//the destructor gets called before hi is printed out and I don't know why thats happening
    }

}


当你这样做的时候

1
foo=creature(choice);

临时creature对象在分配的rhs上创建。一旦语句完成,即在行尾调用它的析构函数。

实际上没有什么需要修复的,但是您可以在读取choice后初始化foo,而不是默认初始化然后分配:

1
2
3
4
5
6
int choice;

cout<<"enter 1 2 or 3 to choose ur monster"<<endl;
cin>>choice;

creature foo(choice);


为了补充其他答案,您的问题涉及"修复析构函数"。没有什么可以修复的,但是由于正在调用析构函数,您试图完成的工作中可能存在一个bug。

当前代码将发生的情况是,可以创建临时副本,而不必跟踪它们。当调用它们的析构函数时,您将无意中减少count变量,可能会给您一个count的负值。

如果希望对象静态count成员变量正确反映创建和销毁的对象的数量,则类缺少用户定义的复制构造函数来跟踪实例的数量。

您需要添加此函数。

1
2
3
4
5
class creature{
public:
    creature(const creature& c) :
         name(c.name), happy_level(c.happy_level) { ++count; }
};

复制或分配时将调用此函数。

活生生的例子:

(原始代码):http://coliru.stacked-crooked.com/a/ea9821e622aa4cdc

(更改代码):http://coliru.stacked-crooked.com/a/b774a896377bdf97

唯一的区别是,原始代码将复制构造函数注释掉,而更改后的代码将复制构造函数保持不变。

注意,在原始代码中,我想知道有多少对象被创建和销毁,但是当最后一个对象被销毁时,我得到了-1的结果。这是不正确的,因为很明显结果应该是0,这意味着所有的生物都会被毁灭。

更改后的代码显示了正确的数字,这是因为临时生物的对象创建被考虑在内。


正如Juanchopanza在回答中指出的那样,

1
foo = creature(choice);

在分配给foo之前创建一个临时生物对象。如果您不希望发生这种情况,请使用

1
creature foo(choice);