为什么我的析构函数被调用,我该如何修复它

时间:2015-05-27 20:23:18

标签: c++ constructor

嘿伙计们,所以我在我的c ++程序中遇到了我的析构函数问题。当我运行程序并接受用户输入时,它突然调用析构函数,然后cout甚至可以在语句中打印。假设用户输入将是一个,因为我设计了这部分代码只接受输入1.我认为析构函数在你离开范围时被调用所以我认为析构函数应该在cout之后被调用至少我将在下面评论的if语句,让你们更容易阅读。如果有人可以解释我的错误并纠正它会很棒!在我的头文件中,我有

#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;
};

在我的实施文件中,我有

#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;
}

在我的主要课程中我有

#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
    }

}

3 个答案:

答案 0 :(得分:8)

当你这样做时

foo=creature(choice);

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

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

int choice;

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

creature foo(choice);

答案 1 :(得分:1)

正如juanchopanza在他的回答中指出的那样,行

foo = creature(choice);

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

创建它
creature foo(choice);

答案 2 :(得分:1)

要添加其他答案,您的问题提到“修复析构函数”。没有什么可以修复的,但是由于调用了析构函数,你可能会遇到一个错误。

您当前的代码会发生什么情况,可能会在没有您跟踪的情况下创建临时副本。当他们的析构函数被调用时,你会无意中递减count变量,可能会给你count的负值。

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

您需要添加此功能。

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,这意味着所有生物都被摧毁。

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