C++:调用了错误的析构函数

C++: Wrong Destructor Called

本文关键字:析构函数 错误 调用 C++      更新时间:2023-10-16

ProjectileNode 的子类。我希望调用Projectile析构函数。

注意:在现实生活中,我有一个Node*列表,它们是ProjectilePlayerEnemy,每个都有自己的析构函数。

Node.h file中没有指定的析构函数(我假设它使用默认析构函数)。

    Node* p = new Projectile();
    delete(p); //Projectile destructor is never called

首先,从你的问题中似乎很清楚ProjectileNode的一个子类(参见这个维基百科条目)。

如果你有一个像Node这样的类是为子类而构建的,那么你应该确保它的析构函数是虚拟的:

class Node
{
...
    virtual ~Node();
};

这将导致编译器调用相应的类s destructor when you删除指向超类的指针。

(另一个问题是它是否应该是纯虚拟的。

>C++是静态类型语言,因此从此语句Node* p = new Projectile();编译器将p视为Node的对象。在析构 p 时,它将仅调用类 Node 的析构函数。

为了克服这种情况,virtual出现了。

法典:

class Node {
  public:
    virtual ~Node() {
      //delete resources allocated in Node class
    }
};
class Projectile : public Node {
  public:
    ~Projectile() {
       //delete resources allocated in Projectile class
     }
};
你必须

使Node的析构函数virtual,默认的析构函数(非虚拟)不能满足这里的需求,即动态多态性不起作用。

class Node {
public:
    virtual ~Node() {}
}

简短回答:

使您的析构函数Node虚拟。

class Node {
  // Stuff...
  virtual ~Node();
};

不那么简短的答案:

Projectile和喜欢继承Node时,数据成员和函数继承自Node。派生类可以重写或替换父类中的实际函数定义。此重写发生在编译时或运行时,具体取决于天气,基类中的函数被声明为"虚拟"。

对于非虚拟析构函数,要调用的析构函数由指针的类型确定。所以即使指针变量p指向Projectile的实例,delete(p)也会调用Node中定义的析构函数。

对于虚拟析构函数

,要调用的析构函数是在运行时确定的。因此,无论指针类型如何,调用的析构函数都将是在 p 指向的对象中定义的析构函数。