在我的赋值运算符方法中,我首先销毁对象管理的所有资源,然后分配,所以:
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管理(它没有被释放)。我是不是记忆没有被解除分配?
答案 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时,我认为没问题
不行。显式析构函数调用结束对象的生命周期。在生命周期结束后,您可能无法访问该对象的成员。行为未定义。
我是否认为记忆没有被解除分配?
你是对的,但这并不重要。
我之所以这么说是因为我可以把它放在一个地方,而不是重写删除代码。
这可以通过编写一个释放资源的函数来实现,并从赋值运算符和析构函数中调用该函数。