【问题标题】:Deleting a pointer to this from class?从类中删除指向 this 的指针?
【发布时间】:2012-04-14 20:19:13
【问题描述】:

我有一个名为SpriteX 的类,它基本上是一个通用精灵。我还有一个名为_Drawables 的类,它有一个成员std::vector<SpriteX*>。在main() 中,我创建的每个精灵都可以插入到_Drawables 容器中,然后可以调用drawAll() 方法来绘制std::vector 中的所有SpriteX 对象。

每个SpriteX 对象都知道指向自身的指针所在的索引,并在其析构函数中设置指向NULL 的指针。但我想完全销毁指针,而不仅仅是将其设置为NULL。但是删除指针安全吗?如果我在析构函数中使用delete,并调用析构函数,会导致循环吗?有什么办法可以释放内存。

【问题讨论】:

  • 旁注:名称_Drawables在C++中是非法的;你应该重命名那个类。以下划线 + 大写字母开头的名称保留用于实现。

标签: c++ pointers memory-management


【解决方案1】:

如果我在析构函数中使用 delete 并调用析构函数,会导致循环吗?

是的,这可能会导致堆栈溢出和崩溃。

但你不需要这样做,因为如果你在析构函数中,你已经在删除内存,对吧? (例如,您没有明确调用我希望的析构函数)

【讨论】:

  • 析构函数本身不会“删除内存”。它只是执行对象的销毁逻辑。内存由delete调用对象的析构函数后释放。
  • 不,你不是。您可以手动调用MyClass::~MyClass,在某些情况下(例如放置新位置)甚至是有意义的。
  • @LuchianGrigore 当精灵超出范围时调用析构函数(即main() 的结尾)。但是你的意思是,析构函数会删除指针持有的内存?
  • @rcplusplus 如果 sprite 超出范围,这意味着您在自动内存中创建它(即您没有使用 new 分配内存)。这意味着内存会自动释放,您不需要(也不应该)显式清除它。
【解决方案2】:

你在这里试图重新发明轮子,但你做得不好(这是一个复杂的轮子)。

在此处使用智能指针,例如std::unique_ptr(如果您使用 C++11)或 boost::shared_ptr

如果我在析构函数中使用delete,并调用析构函数,会导致循环吗?

是的。这毫无意义......首先如何调用析构函数?您实际上是在指针上手动调用析构函数吗?虽然这是可能的,但这很可能是一个非常糟糕的主意。

【讨论】:

    【解决方案3】:

    根据您的操作,您可能希望完全放弃指针而只使用std::vector<SpriteX>

    或者,如果您想要有指针但直到main() 结束才清除它们,请考虑使用boost::ptr_vector。它将为您提供与std::vector<> 相同的语法,但您必须使用指针push_back。此外,它将拥有您的指针的所有权,因此您不必担心删除它们。

    如果您将SpriteX 单独传递给函数,或者如果它们具有复杂的生命周期,请使用std::vector<boost::shared_ptr<SpriteX> >。但是,如果它们在同一范围内定义和删除,我会坚持使用更简单的方法。

    【讨论】:

    • 问题是,我在实际对象上调用移动类型方法,_Drawables 类只是阻止我在每个SpriteX 对象上显式调用draw()
    【解决方案4】:

    使用Boost::shared_ptr<>

    所以声明你的向量是:

    std::vector<boost::shared_ptr<SpriteX> >
    

    然后,当您擦除迭代器或清除条目时,引用计数将归零并释放内存。

    如果您已经在析构函数中,则删除 this 是没有意义的,因为您在析构函数中。

    【讨论】:

      猜你喜欢
      • 2018-08-09
      • 1970-01-01
      • 2011-09-14
      • 2010-09-08
      • 1970-01-01
      • 1970-01-01
      • 2020-03-27
      • 2023-03-17
      • 1970-01-01
      相关资源
      最近更新 更多