C++ 当通过动态强制转换完成向下转换时,不会调用基类的虚拟析构函数

C++ 当通过动态强制转换完成向下转换时,不会调用基类的虚拟析构函数,c++,casting,downcast,C++,Casting,Downcast,当我运行下面的代码时,我遇到了以下问题。 删除派生指针d1不会调用基类的析构函数。删除派生指针d2调用基析构函数。为什么强制类型转换(动态或静态)会影响是否调用基本析构函数 class Base { public : Base() { std::cout<<"Base Ctr"<<std::endl; } virtual ~Base() { std::cout<<"Base Dtr"<<std::endl; } };

当我运行下面的代码时,我遇到了以下问题。 删除派生指针d1不会调用基类的析构函数。删除派生指针d2调用基析构函数。为什么强制类型转换(动态或静态)会影响是否调用基本析构函数

class Base  
{ 
  public :  

  Base() { std::cout<<"Base Ctr"<<std::endl; }  

  virtual ~Base() { std::cout<<"Base Dtr"<<std::endl; }
};

class Derived : public Base  
{ 
  public :  
  Derived() { std::cout<<"Derived Ctr"<<std::endl; }  

  ~Derived() { std::cout<<"Derived Dtr"<<std::endl; }
};

int main()
{  
  Derived* d1 = static_cast<Derived*>(new Base());

  delete d1;

  Derived* d2 = dynamic_cast<Derived*>(new Base());

  delete d2;
}

注意:为了简单起见,我没有在基类中显示虚拟函数(因为基类析构函数最初是虚拟的)。

您的
动态转换在这两种情况下都失败,因为您无法安全地将
基类
向下转换为
派生的
(您的初始对象是
Base
newbase
)。您应该测试动态强制转换的结果

if(!d1) // d1 is nullptr here
    std::cout << "Failed dynamic_cast";
如果(!d1)//d1在这里为null ptr

std::cout此强制转换失败并返回一个
nullptr

Derived* d2 = dynamic_cast<Derived*>(new Base());
因此,将对象泄漏到
d2
后面

为什么强制类型转换(动态或静态)会影响是否调用基本析构函数

class Base  
{ 
  public :  

  Base() { std::cout<<"Base Ctr"<<std::endl; }  

  virtual ~Base() { std::cout<<"Base Dtr"<<std::endl; }
};

class Derived : public Base  
{ 
  public :  
  Derived() { std::cout<<"Derived Ctr"<<std::endl; }  

  ~Derived() { std::cout<<"Derived Dtr"<<std::endl; }
};

int main()
{  
  Derived* d1 = static_cast<Derived*>(new Base());

  delete d1;

  Derived* d2 = dynamic_cast<Derived*>(new Base());

  delete d2;
}
不是,但是删除空指针不会调用任何析构函数。您之所以有空指针,是因为您试图将
动态
a
Base
转换为
派生的
,这显然会失败

事实上,这两个指针都是如此,因此您的问题中的输出来自您未显示的其他代码。淘气!

尝试:

  Base* d1 = new Derived();
  delete d1;
或者更好:

std::unique_ptr<Base> d1 = std::make_unique<Derived>();

请发布一些可编译的代码。你的意思是添加标题文件@juanchopanza吗?@PranavKapoor:你的问题也被打断了,因为这个程序的输出,即使是“修复”了,不是你所说的。是的,但更重要的是,将
更改为
结构
,以使事物
公开
。第一个是静态的,我不太会发问(事实上,这是我的第一个问题),请让我放松一下。我的问题与向下投射有关。你的答案与向上投射有关。
std::unique_ptr<Base> d1 = std::make_unique<Derived>();
Derived d1;
Base *b = &d1;