【问题标题】:Does deleting an object in c++ also delete other objects referenced by a pointer contained in the object在c ++中删除对象是否也会删除对象中包含的指针引用的其他对象
【发布时间】:2021-10-16 21:19:58
【问题描述】:

我最近在类和指针方面做了很多工作,遇到了以下场景:

我有一个 DataBase 类的对象,它包含一个 std::vector 指向 DataSet 类对象的指针,其中包含一个浮点向量。 现在的问题是: 如果我希望删除所有这些 Datasets 及其存储的浮点数,是否只需删除 DataBase 类的对象就足够了,还是我首先需要删除所有引用的 DataSets 然后删除 DataBase 对象?

两个类的代码:

class Dataset
{
public:
    Dataset();
    ~Dataset();
    std::vector<float*>* InputValues = new std::vector<float*>;
    std::vector<float*>* ExpectedValues = new std::vector<float*>;
};

class DataBase 
{
public:
DataBase();
    ~DataBase();
    int AddedDataSets = 0;
    std::vector<Dataset*>* DataSets = new std::vector<Dataset*>;
};

这些 vectos 将被其他函数填充,到最后,我想再次删除它们:

删除“数据库对象的名称”;

【问题讨论】:

  • 这取决于DataBase类的析构函数做了什么。
  • 不,这是要避免使用原始指针和new 的原因之一。您甚至不需要这里的动态对象,只需从您的代码中删除所有指针和new,它就会起作用。 std::vector&lt;float*&gt;* InputValues 应该只是 std::vector&lt;float&gt; InputValues;。这段代码看起来像是受到 Java 或 C# 的启发。 new 在 C++ 中不如在那些语言中有用,C++ 鼓励值语义。在实践中,在现代 C++ 中,几乎没有理由使用 newdelete
  • Unelated:如果你需要一个析构函数,你可能还需要特殊的成员函数来正确处理复制和移动类实例。详情请咨询the Rule of Three/Five/Zero
  • 删除对象就足够了。如果不是,那是因为您设计了错误的对象。它应该自己清理。如果没有,它就坏了。
  • 在上述所有用例中,无需使用指针或new 操作。使它们成为普通对象,一切都会按预期工作。

标签: c++ class pointers


【解决方案1】:

没有。基类和普通成员等子对象将被删除。但指向的对象不会。

当然,如果您将这些地址保存在智能指针中,情况就会改变;也就是它们的全部要点:如果条件正确,智能指针的析构函数会删除指针对象。

如果您使用普通指针,您必须检查条件并可能自己删除指针。像std::vector 这样的类就是这样做的:它们包含一个指向动态分配内存的指针,并在调用每个元素的析构函数后释放它。实施一个是值得的练习。也很清楚为什么向量不能删除其元素中的指针指向的对象:完全不清楚内存是动态分配的。你可以推送全局变量的地址,如果传递给delete,这会使程序崩溃。地址也有可能存储在其他地方,在那里将进行另一次删除它们的尝试。这些谁承担责任并有权删除对象的考虑涉及所谓的所有权。

请注意,在分配或复制此类对象时,通常还必须注意指针和指针。默认复制操作是复制地址;如果析构函数稍后删除该地址处的对象,那么如果您的类的两个独立对象指向同一个地址,那将是一场灾难。

【讨论】:

  • 好的,这已经很有帮助了。如果我理解正确:如果我想手动删除所有内容,我需要在 for 循环中删除单个指针浮点数,然后在向量上调用析构函数,在持有向量的对象上调用析构函数等等等等?或者,我必须用智能指针替换指针,如果我删除指针本身,它会自动删除指针,对吗? ^^
  • @FLOROID 是的。但是手动的方式很麻烦。正如弗朗索瓦所说,向量应该是常规对象,而不是指针;当您的类对象被销毁时,它将至少自动调用 vector 析构函数。进入第 2 级 ;-):向量调用其元素的析构函数,但它们对普通指针没有任何作用。如果您使用 智能指针 作为元素,它们的析构函数将做正确的事情(例如,对于 unique_ptr 只需在包含的原始地址上调用 delete)。并且智能指针还负责(或防止)复制和分配。
猜你喜欢
  • 2013-02-11
  • 1970-01-01
  • 1970-01-01
  • 2021-02-07
  • 2017-04-24
  • 1970-01-01
  • 1970-01-01
  • 2015-06-08
  • 2011-05-02
相关资源
最近更新 更多