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

C++ C++;:调用了错误的析构函数,c++,destructor,C++,Destructor,射弹是节点的子类。 我希望调用抛射析构函数 注意:在真实场景中,我有一个节点*列表,它们是投射物、玩家或敌人,每个节点都有自己的析构函数 节点在.h文件中没有指定的析构函数(我假设它使用默认析构函数) 您必须将节点的析构函数设置为虚拟的,默认的析构函数(非虚拟的)不能满足此处的需要,即动态多态性无法工作 class Node { public: virtual ~Node() {} } 首先,从您的问题中可以很清楚地看到,sparket是节点的子类(请参阅) 如果您有一个为子类化而构建

射弹
节点
的子类。 我希望调用
抛射
析构函数

注意:在真实场景中,我有一个
节点*
列表,它们是
投射物
玩家
敌人
,每个节点都有自己的析构函数

节点
.h文件
中没有指定的析构函数(我假设它使用默认析构函数)


您必须将
节点的析构函数
设置为
虚拟的
,默认的析构函数(非虚拟的)不能满足此处的需要,即动态多态性无法工作

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

首先,从您的问题中可以很清楚地看到,
sparket
节点的子类(请参阅)

如果您有一个为子类化而构建的类,如
Node
,那么您应该确保其析构函数是虚拟的:

class Node
{
...
    virtual ~Node();
};
这将导致编译器在删除指向超类的指针时调用相应的类
s析构函数


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

C++是静态类型的语言,因此从这条语句中,
Node*p=newspolder()编译器将p视为节点的对象。在销毁p时,它将仅调用类
节点的析构函数

为了克服这种情况,
virtual

代码:

简短答复:

节点中的析构函数设置为虚拟

class Node {
  // Stuff...
  virtual ~Node();
};
不那么简单的回答:

当继承
节点时,数据成员和函数从
节点继承。派生类可以重写或替换父类中的实际函数定义。此重写发生在编译时或运行时,具体取决于基类中的函数是否声明为“虚拟”

对于非虚拟析构函数,要调用的析构函数由指针的类型决定。因此,即使指针变量
p
指向
投射物的一个实例,
delete(p)
将调用
节点中定义的析构函数


对于虚拟析构函数,将在运行时确定要调用的析构函数。因此,无论指针类型如何,调用的析构函数都将是由
p

指向的对象中定义的析构函数。您的意思是
投射物
继承自
节点
(如果是这样,
super类
投射物
节点
相关的术语是错误的)?默认析构函数不是虚拟的。如果它还不是虚拟的,请打开编译器警告级别(-Wall在g++中应该足够了)你会看到编译器告诉你,你写的东西行不通。你知道,我从来没有尝试过纯虚拟析构函数。这将在明天进行实验。为什么不是所有函数都是虚拟的?让它们不虚拟有好处吗?有几个原因。其中之一是有一个运行时oveReHAD与使用它们相关,C++哲学是“只为你使用的特性付费”。Bjarne Stroustrup有一本关于这些东西的书,比如“C++语言的设计和进化”。
class Node {
  public:
    virtual ~Node() {
      //delete resources allocated in Node class
    }
};

class Projectile : public Node {
  public:
    ~Projectile() {
       //delete resources allocated in Projectile class
     }
};
class Node {
  // Stuff...
  virtual ~Node();
};