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

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

本文关键字:何修复 调用 我的 析构函数 为什么      更新时间:2023-10-16

我的c++程序中的析构函数有问题。当我运行程序并接受用户输入时,它在cout甚至可以在语句内打印之前突然调用析构函数。假设用户输入为1,因为我将这部分代码设计为只接受输入1。我认为析构函数在离开作用域时被调用,所以我认为析构函数应该至少在if语句的cout之后被调用,我将在下面注释,以便你们更容易阅读。如果有人能解释并纠正我的错误,那就太好了!在我的头文件中有

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

在main类中有

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

当你这样做的时候

foo=creature(choice);

在赋值的RHS上创建一个临时creature对象。它的析构函数在语句结束时被调用,即在行尾。

没有什么需要修复的,但是你可以在读取choice后初始化foo,而不是默认初始化然后赋值:

int choice;
cout<<"enter 1 2 or 3 to choose ur monster"<<endl;
cin>>choice;
creature foo(choice);

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

foo = creature(choice);

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

创建它
creature foo(choice);

添加到其他答案中,您的问题提到了"修复析构函数"。没有什么需要修复的,但是由于调用析构函数,可能会在您尝试完成的任务中出现错误。

当前代码会发生的情况是,可能会创建临时副本而不跟踪它们。当调用它们的析构函数时,您会无意中减少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,这意味着所有生物都被摧毁了。

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

相关文章: