当类包含空析构函数时是否存在差异

时间:2013-05-19 11:14:07

标签: c++ destructor

这个类::

之间有区别吗?
class Osoba{
public:
char* imie;
int wiek;

Osoba(char* imie, int wiek){
    this->imie = imie;
    this->wiek = wiek;
}
};

没有析构函数~Osoba(){delete imie;}或没有它?这两种情况都是正确的吗?

3 个答案:

答案 0 :(得分:2)

有一个重要的区别。

你从构造函数中得到char* imie(暗示你没有new那个),所以你不应该delete那样。然后不要使用delete *imie;,除非你知道你在做什么。

new指针负责delete它的类/对象,以这种方式组织代码。

答案 1 :(得分:1)

不同之处在于,在第一种情况下,当Osoba的生命结束时,没有什么特别的事情发生。在第二种情况下,您在imie上调用删除,这可能是也可能不是。

什么是正确的取决于Osoba是否应该由imie拥有对象指针广告。如果没有,那么您不需要用户定义的析构函数。如果是,那么你需要析构函数,加上赋值运算符和复制构造函数,或者你需要禁用它们。这样做的原因是,如果不处理赋值和使用大小写复制,最终可能会有许多指向同一对象的实例。所有这些实例都将尝试删除同一个对象。请参阅rule of three

答案 2 :(得分:1)

不,请勿删除imie中的Osoba,因为Osoba不知道imie的创建方式。

一般来说,释放内存是分配它的人的责任。在您的情况下,无论谁调用构造函数Osoba(char* imie, int wiek),都必须先创建imie。这可以通过new,malloc或strdup或任何其他分配内存的东西来完成。它甚至可能是没有从堆中分配的东西。

关键是Osobaimie一无所知,所以可能它不应该删除它。分配imie的人应该删除它。

事实上,Osoba可能复制字符串,即

this->imie = strdup(imie)

在这种情况下,你应该在析构函数中free(imie)。它应该复制字符串的原因是因为调用者可能做了类似这样的事情:

Osoba* SomeFunction()
{
    char X[100];
    sprintf(X, "I will be gone when SomeFunction returns");
    return new Osoba(X, 0);
}

在这种情况下,当SomeFunction返回时X将消失,而Osoba将有一个指向随机存储器的指针。

但要回答您的问题,请不要删除imie中的Osoba,因为Osoba不知道imie是如何创建的,除非您决定复制它,在这种情况下你应该在析构函数中释放副本。