析构函数调用和指针

工作组

这是我的问题,我有一个函数,该函数包含以下内容:

void function() {  
    entity e; //entity is just a class  
    entities.push_back(e); //entities is a vector of entity objects  
}

这是令我困扰的事情。“ e”包含指向另一个对象的指针。调用实体的析构函数时,它将删除该指针。由于'e'和实体中的实体都指向同一位置,因此,如果我对实体中的该指针执行某些操作,(在函数外部)它将产生错误,因为指针中的所有内容均会在函数被删除后立即删除。回来。解决此问题的最佳方法是什么?

6502

C ++是一种“基于副本”的语言,例如,的容器Entity确实会将您提供给它的实体的副本放入该容器中。

副本在很多地方都是用C ++编写的,因此最好是您的类正确地支持它们,或者完全禁止它们。

您的类包含一个指向其他数据的指针:当您复制该类的实例时会发生什么?如果可以复制指针,那么显然不能在析构函数中删除指向的对象,因为仍然存在的副本将指向已删除的对象。

有一个简单的规则可以帮助避免这种错误,被称为“三个规则”。如果您已明确编码

  • 复制构造函数
  • 驱逐舰
  • 赋值运算符

在课堂上,那么您很可能需要全部三个。

在这种情况下,您有一个不是默认析构函数的析构函数(因为删除了指向对象),因此您还需要告知在复制构造或赋值时该怎么做。

如果您希望该类不可复制,则只需确保

struct Entity {
    Object *o;

    Entity(Object *o) : o(o) {
        ...
    }

    ~Entity() {
        delete o;
    }

private:
    // Taboo... this should just never happen!!!
    // Here is a declaration, but no implementation will be written
    Entity(const Entity& other);      // Copy constructor
    Entity& operator=(const Entity&); // Assignment
};

声明禁止的操作private将确保用户代码永远不会调用它们(这将是编译时错误),而仅声明它们而不提供实现将确保即使类代码本身也不会错误地调用它们(您会得到链接时错误)。

但是,在这种特定情况下,这将禁止您的代码将Entity实例放入容器中(容器中的元素必须被复制)。您可以将Entity 指针放在容器中(可以复制指针,因此std::vector<Entity *>forentities是合法的),但是您将负责处理对象的正确生命周期(谁应该调用析构函数,什么时候应该发生?)。

另一方面,如果您有一个指向类内部数据的指针,并且希望允许复制该类的实例,则可以:

  • 也复制指向的数据
  • 在不同实例之间共享指向的数据

对于第二种解决方案,一种常见的方法是使用“引用计数”指针,即,指向数据“知道”有多少个指针正在引用它,并且仅在此计数达到0时才会销毁。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章