Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;虚拟方法不工作_C++_Function_Inheritance_Methods_Virtual - Fatal编程技术网

C++ C++;虚拟方法不工作

C++ C++;虚拟方法不工作,c++,function,inheritance,methods,virtual,C++,Function,Inheritance,Methods,Virtual,给出以下示例: class BaseClass { BaseClass() { }; virtual ~BaseClass() { this->Cleanup(); }; virtual void Cleanup() { // Do cleanup here. }; }; class Level1DerivedClass : public BaseClass { Level1DerivedClass() { };

给出以下示例:

class BaseClass
{
  BaseClass()
  {
  };

  virtual ~BaseClass()
  {
    this->Cleanup();
  };

  virtual void Cleanup()
  {
    // Do cleanup here.
  };
};

class Level1DerivedClass : public BaseClass
{
  Level1DerivedClass()
  {
  };

  virtual ~Level1DerivedClass()
  {
  };

  virtual void Cleanup()
  {
    // Call my base cleanup.
    BaseClass::Cleanup();

    // Do additional cleanup here.
  };
};

class Level2DerivedClass : public Level1DerivedClass
{
  Level2DerivedClass()
  {
  };

  ~Level2DerivedClass()
  {
  };

  void Cleanup()
  {
    // Call my base cleanup.
    Level1DerivedClass::Cleanup();

    // Do additional cleanup here.
  };  
};


main()
{
  Level2DerivedClass * derived2 = new Level2DerivedClass();
  delete derived2;
  return 0;
}
当我删除我的派生类引用时,我希望流程如下所示:

  • 执行Level2DerivedClass析构函数
  • 因为Level1DerivedClass析构函数是虚拟的,所以将执行它
  • 因为基类析构函数是虚拟的,所以它将被执行
  • 由于基类::Cleanup和Level1DerivedClass::Cleanup都是虚拟的,因此基类析构函数中基类“this”指针的调用将执行派生最多的类的实现-Level2DerivedClass::Cleanup
  • Level2DerivedClass::Cleanup调用其父级的清理实现
  • Level1DerivedClass::Cleanup调用其父级的清理实现
  • 所发生的事情是,它正在按我所期望的方式为每一级继承(1-3)调用析构函数。但是当从基类析构函数调用此->Cleanup()时,它只执行自己的实现。我不理解为什么会发生这种情况,因为通常当您实例化一个派生类指针,将其转换为基类指针,并从基类指针调用一个虚拟方法(在本例中为“this”)时,它仍然运行派生类实现(整个“virtual”点,是吗?)。在我的示例中,永远不会调用Level2DerivedClass::Cleanup和Level1DerivedClass::Cleanup

    我这样设置它的原因是我希望能够调用我的清理代码,而不必销毁我的对象,这就是为什么我要将它从实际的析构函数体中抽象出来

    如果你有更合适的建议,我洗耳恭听。但我也想解释一下为什么我的设置不起作用-我误解了什么

    提前感谢您抽出时间。

    经验法则是:

    他们的行为不像你想象的那样;随着每个析构函数的完成,此的动态类型将得到有效修改。在C++标准中,[C.Cordor ]:

    当从构造函数(包括mem初始值设定项或 非静态数据成员的大括号或相等初始值设定项)或析构函数中的大括号或相等初始值设定项,以及 调用应用于正在构造或销毁的对象,调用的函数是 构造函数或析构函数自己的类或其基之一,但不是在派生类中重写它的函数 从构造函数或析构函数的类,或在最派生的 反对


    正确的做法是:在析构函数中清理你自己,并且只清理你自己。不要跟着你的孩子或父母打扫

    如果你不想从析构函数中清理东西,那你就错了。在C++中,我们有一个叫做RAII的小东西,资源获取是初始化。但也有它的双重属性,它似乎没有一个正式的名字,但这里有一个可能起作用的东西:RDID,资源处置就是破坏


    当然,你不必坚持RAII/RDID哲学,但那不是C++方式。< /P>编译吗?错误:“BaseClass::BaseClass()”是privateAlessandro,抱歉。这不是真正的代码,只是一个示例,代表了我在程序中要做的事情。谢谢,奥利!这就是我所缺少的。谢谢你的解释。因此,一个可能的解决方案是在每个类中放置一个非虚拟Cleanup()方法,并从每个类自己的析构函数调用它。虚拟析构函数仍将确保调用所有析构函数-Cleanup()不会像我现在这样由虚拟实现处理。听起来不错?谢谢NM。我一直在学习C++的新东西,这不是我以前遇到过的。关于最佳实践的好提示。