这个类::
之间有区别吗?class Osoba{
public:
char* imie;
int wiek;
Osoba(char* imie, int wiek){
this->imie = imie;
this->wiek = wiek;
}
};
没有析构函数~Osoba(){delete imie;}
或没有它?这两种情况都是正确的吗?
答案 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或任何其他分配内存的东西来完成。它甚至可能是没有从堆中分配的东西。
关键是Osoba
对imie
一无所知,所以可能它不应该删除它。分配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
是如何创建的,除非您决定复制它,在这种情况下你应该在析构函数中释放副本。