在赋值运算符方法中调用对象的析构函数

时间:2017-01-26 17:08:42

标签: c++ memory vector destructor

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

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]动物会调用自己的析构函数,然后分配aNumber,但内存由vector管理(它没有被释放)。我是不是记忆没有被解除分配?

2 个答案:

答案 0 :(得分:4)

在析构函数调用之后,持有该对象的内存区域只是原始内存。

您无法在那里使用仅分配给明显成员的结果。

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

但不要这样做。

它充满危险,绝对是敌对的致命领地,除此之外还有臭和不洁。

而不是

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

DO

vector<int> buffer;

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

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

在其他新闻中,签名

Animal& operator= (Animal& other)

只允许您从使用左值表达式指定的非const Animal对象中分配(即不是临时表达式),因为只有那些可以绑定正式参数对非{{{{ 1}}。

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

const

表示不修改实际参数的意图。

答案 1 :(得分:2)

  

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

你可能没有。

  

所以当我在调用析构函数后分配aNumber时,我认为没问题

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

  

我是否认为记忆没有被解除分配?

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

  

我之所以这么说是因为我可以把它放在一个地方,而不是重写删除代码。

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