【问题标题】:Calling an object's destructor in its assignment operator method在赋值运算符方法中调用对象的析构函数
【发布时间】:2017-06-12 06:05:37
【问题描述】:

在我的赋值运算符方法中,我首先销毁对象管理的所有资源,然后进行分配,所以:

struct Animal
{
    int aNumber;
    int * buffer;
    Animal() { buffer = new int[128]; }
    Animal& operator= (Animal& other) 
    { 
      if (this != &other){
      delete [] buffer; 
      //this->~Animal();     // I'm wondering if I can call this instead of deleting buffer here.
      aNumber = other.aNumber;
    }
    ~Animal() { delete[] buffer;}
};

我问这个问题的原因是,我不需要重写删除代码,而是可以将它放在一个地方。另外,我不认为调用析构函数会释放内存,所以当我在调用析构函数后分配aNumber时,我认为没关系。当我说内存没有被释放时,我的意思是,例如,如果我有一个vector<Animal>,并且vector 调用了vector[0] 的复制赋值运算符,vector[0] Animal 将调用它自己的析构函数,然后分配@987654327 @,但内存由向量管理(它没有被释放)。内存没有被释放是对的吗?

【问题讨论】:

  • 只是不要[[[[
  • 请更喜欢使用std::vector<int> 而不是动态分配内存。您将简化程序并减少内存管理的麻烦(std::vector 为您管理内存)。

标签: c++ memory vector destructor


【解决方案1】:

我想知道是否可以调用 [析构函数] 而不是在这里删除缓冲区。

你可能不会。

所以当我调用析构函数后分配aNumber时,我认为没关系

不正常。显式的析构函数调用结束对象的生命周期。在对象的生命周期结束后,您可能无法访问对象的成员。行为未定义。

内存没有被释放是对的吗?

你是对的,但这并不重要。


我问这个的原因是为了不用重写删除代码,我可以把它放在一个地方。

这可以通过编写一个释放资源的函数来实现,并从赋值运算符和析构函数中调用该函数。

【讨论】:

  • 谢谢。我不能在赋值运算符中调用析构函数的原因是什么?
  • @TitoneMaurice 查看编辑并回答您的一个问题。这也应该回答您评论中的答案。
【解决方案2】:

在调用析构函数后,保存对象的内存区域就是原始内存。

您不能使用仅分配给那里的明显成员的结果。

它需要一个构造函数调用来在那里重新建立一个对象。

但不要这样做。

这里充满了危险,绝对是充满敌意的致命领域,而且它又臭又脏。


代替

int* buffer;
Animal() { buffer = new int[128]; }

vector<int> buffer;

并在向其中添加项目时根据需要扩展该缓冲区,例如通过push_back

std::vector 为您自动执行内存管理,并保证正确。没有错误。容易得多。


在其他新闻中,签名

Animal& operator= (Animal& other)

只允许您从用左值表达式指定的非const Animal 对象(即非临时对象)进行赋值,因为只有那些才能将形式参数的引用绑定到非const

解决此问题的一种方法是添加const

Animal& operator= (Animal const& other)

传达不修改实际参数的意图。

【讨论】:

    猜你喜欢
    • 2014-06-19
    • 2014-11-27
    • 2012-04-01
    • 2014-04-18
    • 2017-10-06
    • 1970-01-01
    • 2013-03-26
    • 2011-02-08
    • 2020-04-10
    相关资源
    最近更新 更多