#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对象的基本部分?
答案 0 :(得分:21)
可能。
由于base
没有虚拟析构函数,因此您的代码会显示未定义的行为。什么都可能发生。它可能看起来像你期望的那样工作。它可能泄漏内存。它可能会导致您的程序崩溃。它可能会格式化您的硬盘。
要求引用。 C ++11§5.3.5/ 3指出,对于标量delete
表达式(即,不是delete[]
表达式):
如果要删除的对象的静态类型与其动态类型不同,则静态类型应为要删除的对象的动态类型的基类,并且 静态类型应具有虚拟析构函数或行为未定义。
静态类型(base
)与动态类型(derv
)不同,静态类型没有虚拟析构函数,因此行为未定义。
答案 1 :(得分: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,以确保在删除指向派生类对象的基类指针时调用派生类析构函数。
我们可以说'当派生类动态创建成员时,析构函数必须是虚拟的'。
答案 2 :(得分:-1)
您的代码中没有内存泄漏。如果需要在派生类析构函数中释放一些内存,则会发生内存泄漏。