C++ 继承中的析构函数

C++ 继承中的析构函数,c++,inheritance,destructor,C++,Inheritance,Destructor,当我阅读下面的代码时,我有疑问。也就是说,为什么在下面的代码中,即使派生类的对象超出范围,也不会调用派生类的析构函数: #include "stdafx.h" #include <iostream> #include <conio.h> using namespace std; class ClassA { protected: int width, height; public: void set_values(int x,

当我阅读下面的代码时,我有疑问。也就是说,为什么在下面的代码中,即使派生类的对象超出范围,也不会调用派生类的析构函数:

#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;

class ClassA
{
    protected:
        int width, height;
    public:
      void set_values(int x, int y)
      {
        width = x;
        height = y;
      }
      virtual int area()
      {
        return 0;
      }
      ~ClassA()
      {
         cout << "base class destructor called" << endl;
      }
 };

class ClassB : public ClassA
{
      public :
   int area()
   {
     return (width * height);
   }
   ~ClassB()
       {
      cout << "derived class destructor called" << endl;
   }
 };


 int main()
 {
   ClassA *Ptr = NULL;
   ClassB Obj;
   Ptr = &Obj;
   Ptr->set_values(10, 20);
   cout << Ptr->area() << endl;
   delete Ptr;
     return 0;
 }
#包括“stdafx.h”
#包括
#包括
使用名称空间std;
甲级
{
受保护的:
int宽度、高度;
公众:
无效集合_值(整数x,整数y)
{
宽度=x;
高度=y;
}
虚拟整数区域()
{
返回0;
}
~ClassA()
{

不能在基类中使析构函数
为虚拟的
。否则,它调用基类的析构函数

class ClassA
{
// ...
      virtual ~ClassA()
      {
         cout << "base class destructor called" << endl;
      }
};
A类
{
// ...
虚拟~ClassA()
{

不能在基类中使析构函数
为虚拟的
。否则,它调用基类的析构函数

class ClassA
{
// ...
      virtual ~ClassA()
      {
         cout << "base class destructor called" << endl;
      }
};
A类
{
// ...
虚拟~ClassA()
{

cout您不应该对指向派生类对象的基类指针调用
delete
,除非基类析构函数是
virtual
,否则您得到的是未定义的行为

基类中的析构函数需要标记为
virtual

virtual ~ClassA(){}

除非基类析构函数是
virtual
,否则不应在指向派生类对象的基类指针上调用
delete
,否则得到的是未定义的行为

基类中的析构函数需要标记为
virtual

virtual ~ClassA(){}

是的,我知道..但删除ptr后,基类析构函数将调用,然后控制返回,超出程序意味着它超出范围(派生类对象“Obj”将超出范围),但即使派生类对象Obj超出范围,为什么不调用派生类的析构函数。@Nagaraderkantesh:“然后控制返回“--您已经调用了未定义的行为。您不能说控件下一步要去哪里,因为如果任何地方有未定义的行为,整个程序的行为都是未定义的。是的,我知道..但是删除ptr后,基类析构函数将调用,然后控件返回,超出程序范围意味着它超出范围(派生类对象“Obj”将超出作用域)但即使派生类对象Obj超出作用域,为什么不调用派生类的析构函数。@Nagaraderkantesh:“然后控件返回”--您已经调用了未定义的行为。您无法说出控件下一步的位置,因为如果任何地方有未定义的行为,整个程序的行为都是未定义的。即使析构函数是虚拟的,对指向局部变量的指针调用
delete
仍然是未定义的行为。@SteveJessop:真的!我不知道塞德it@Steve:那么我们不应该删除指针,只要我们声明并使用它…?@nagaradderKantesh:只有当有一个
new
被调用时,才调用
delete
,否则就不会调用。你拥有的是一个指向本地/自动对象的指针。当作用域
{
在其中声明结束。它不需要显式释放。@Alok Save:那么,如果我没有删除指针,它仍将保留导致内存泄漏的对象地址na..?即使析构函数是虚拟的,对指向局部变量的指针调用
delete
仍然是未定义的行为。@SteveJesso真的!我错过了it@Steve:那么我们不应该删除指针,只要我们声明并使用它…?@nagaradderKantesh:只有当有一个
new
被调用时,才调用
delete
,否则不会调用。你拥有的是一个指向本地/自动对象的指针。当作用域<代码>{}
在其中声明结束。它不需要显式释放。@Alok Save:那么如果我没有删除指针,它仍将保留导致内存泄漏的对象的地址na。。?