11
#include <iostream>
using namespace std;
class base
{
   int a;
 public: 
   base() {a =0;}
 };
 class derv :public base
 {
   int b;
  public:
   derv() {b =1;}
 };
 int main()
 {
    base *pb = new derv();
    delete pb;
 }

我在 derv 类中没有虚拟析构函数,它是否只删除 derv 对象的基础部分?

4

3 回答 3

21

它可能。

因为base没有虚拟析构函数,所以您的代码表现出未定义的行为。任何事情都可能发生。它可能看起来像你期望的那样工作。它可能会泄漏内存。它可能会导致您的程序崩溃。它可能会格式化您的硬盘驱动器。

请求引用。C++11 §5.3.5/3 指出,对于标量delete表达式(即,不是delete[]表达式):

如果待删除对象的静态类型与其动态类型不同,则静态类型应为待删除对象动态类型的基类,且静态类型应具有虚析构函数或行为未定义。

静态类型 ( base) 与动态类型 ( derv) 不同,静态类型没有虚拟析构函数,因此行为未定义。

于 2012-01-06T01:00:38.737 回答
0

在您的源代码中没有内存泄漏,因为您没有任何动态创建的成员变量。

考虑案例 1 下面的修改示例:

#include <iostream>
using namespace std;
class base
{
   int a;
 public: 
   base() {a =0;}
   ~base() 
     {
       cout<<"\nBase Destructor called";

     }
 };
 class derv :public base
 {
   int *b;

  public:
   derv() { b = new int;}
  ~derv()
  {
      cout<<"\nDerv Destructor called"; 
      delete b;
  }
 };
 int main()
 {
    base *pb = new derv();
    delete pb;
 }

在这种情况下,输出将是,

   Base Destructor called

在这种情况下存在内存泄漏,因为 'b' 是使用 'new' 动态创建的,应该使用 'delete' 关键字将其删除。由于没有调用 derv 析构函数,因此没有删除它,因此存在内存泄漏。

考虑以下情况 2:

#include <iostream>
using namespace std;
class base
{
   int a;
 public: 
   base() {a =0;}
   virtual ~base() 
     {
       cout<<"\nBase Destructor called";

     }
 };
 class derv :public base
 {
   int *b;

  public:
   derv() { b = new int;}
  ~derv()
  {
      cout<<"\nDerv Destructor called"; 
      delete b;
  }
 };
 int main()
 {
    base *pb = new derv();
    delete pb;
 }

在情况 2 输出将是,

Derv Destructor called 
Base Destructor called

在这种情况下,没有内存泄漏。因为调用了 derv 析构函数并且 b 被删除了。

析构函数可以在基类中定义为Virtual,以确保在删除指向派生类对象的基类指针时调用派生类析构函数。

我们可以说“当派生类动态创建成员时,析构函数必须是虚拟的”。

于 2012-01-06T12:37:08.220 回答
-1

您的代码中没有内存泄漏。如果您需要在派生类析构函数中释放一些内存,就会发生内存泄漏。

于 2012-01-06T01:06:26.067 回答