对象向量的析构函数

4

你好,

我在我的类Ordinateur中有一个* Composant的向量:

class Ordinateur {

string type;
vector<Composant*> Composants;

...

}

我可以帮忙翻译。这段文字是关于编程的,询问如何编写析构函数,因为在StackOverflow上看到了很多相互矛盾的答案,所以有些困惑。
第一个版本:
virtual ~Ordinateur()
{
    for (int i = 0; i < Composants.size(); i++)
    {
        delete Composants[i];
    }
    Composants.clear();
}

第二个版本
virtual ~Ordinateur()
{
    Composants.clear();
}

关于什么?
 virtual ~Ordinateur()
{
    for (int i = 0; i < Composants.size(); i++)
    {
        delete Composants[i];
    }

}

我想避免内存泄漏...


5
使用智能指针。不需要编写任何内容。 - Ed Heal
我正在一个项目上工作,我们不能使用智能指针... - Mxsky
3
为什么不行?似乎非常有限制性。 - Ed Heal
clear() 在这两种情况下都是无用的。显然,vector 会自己处理! - Jonathan Wakely
1
这些相互矛盾的答案在哪里?正确编写析构函数的方法是毫无争议的,如果有任何其他建议,它们需要进行修正。 - Jonathan Wakely
4个回答

5

如果您使用了 new Composant(); 分配 Composant 元素,请使用第一个版本,否则第二个版本将会出现内存泄漏。

virtual ~Ordinateur()
{
    for (int i = 0; i < Composants.size(); i++)
    {
        delete Composants[i]; // this is needed to free the memory
    }
    // Composants.clear(); // not needed vector cleans itself up
}

然而,你可以考虑做以下操作:
class Ordinateur {

    std::string type;
    std::vector<std::unique_ptr<Composant>> Composants;

    ...

}

如果您不需要编写析构函数,那么元素会自行删除。在析构函数中无需调用Composants.clear();,因为当您的对象被销毁时,向量会自动执行此操作。


4
如果向量拥有它们并且它们指向new的对象,则您的第一个变体是正确的。
调用vector::clear()不是必需的。无论如何,它将由析构函数完成。除了浪费CPU周期外,它没有造成任何坏处。
你仍然应该使用智能指针,这样你就不会遇到这些问题。

1
调用 clear() 是不必要的,因为当向量被销毁时会自动清除。 - NathanOliver

1
如果您不使用智能指针,那么第一种解决方案是正确的。

1
首先,在析构函数中调用clear()是多余的。
除此之外,具体情况要看情况而定。
大致上,你的vector<Composant*> Composants;可能有两种不同的含义:
  1. Composants观察在其他地方分配和释放的Composant对象。在这种情况下,您的第二个版本是正确的,因为如果您只观察属于别人的东西,那么您不想销毁它。在现代C++中,这通常是原始指针的唯一好用例。

  2. Composants通过自己(使用new)分配Composant对象。在这种情况下,Componsants也负责释放,您的第二个版本基本上是正确的。但是,在现代C++中,您通常不直接使用newdelete。相反,您使用std::unique_ptr,以便自动处理释放。对于某些用例,也可以使用std::shared_ptr

还有第三种可能。也许根本不需要动态分配 Componsant 对象。也许像 vector<int> 或者 <vector<string>> 一样,vector<Componsant> 就足够了。C++ 初学者往往会过度使用动态分配(这可能是受到像 Java 这样的语言的影响,其中自定义类型的实例总是需要用 new 关键字创建)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接