【问题标题】:Why is my destructor being called and how can I fix it [duplicate]为什么我的析构函数被调用,我该如何修复它[重复]
【发布时间】:2015-08-10 03:03:57
【问题描述】:

我的 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
    }

}

【问题讨论】:

  • 它被称为“析构函数”。
  • foo = creature(choice); 中,您创建一个匿名实例(creature(choice)),在foo 上调用creature &amp; operator=(const creature &amp;),然后销毁该匿名实例。另外,它是“析构函数”,顺便说一句。
  • 您的 count 变量并未反映实际情况。您未能添加复制构造函数和赋值运算符来计算这些实例。相反,您正在减少您甚至没有跟踪的对象实例的计数。
  • @TheParamagneticCroissant:这几乎不值得指出。即使没有上下文,deconstructor 也完美地描述了它是什么。

标签: c++ constructor


【解决方案1】:

当你这样做时

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);

【讨论】:

  • 原来的creature (foo) 不是被破坏了吗?
  • @Amit 它在main() 退出时被销毁,而不是在显示的语句期​​间。
  • @Amit 不,它几乎等同于creature __anon(choice); foo.operator=(__anon); __anon.~creature();
  • @Darraptor 因为choice 没有有用的价值。
  • @juanchopanza 哦,你说得对,哈哈,谢谢你,我得到你的解释,我的代码几乎可以工作了(我只需要添加更多的东西,但我可以处理)
【解决方案2】:

正如 juanchopanza 在他的回答中指出的那样,这条线

foo = creature(choice);

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

创建它
creature foo(choice);

【讨论】:

    【解决方案3】:

    要添加到其他答案,您的问题是指“修复析构函数”。没有什么可修复的,但是由于调用了析构函数,您尝试完成的工作可能存在错误。

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

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

    【讨论】:

      猜你喜欢
      • 2010-12-21
      • 2022-11-15
      相关资源
      最近更新 更多