#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条答案
按热度按时间0aydgbwb1#
可能吧
因为
base
没有虚析构函数,所以代码会表现出未定义的行为。什么事都有可能发生。它可能会像你期望的那样工作。它可能会泄漏内存。它可能会导致你的程序崩溃。它可能会格式化您的硬盘驱动器。要求提供引证。C++11 §5.3.5/3规定,对于标量
delete
表达式(即,不是delete[]
表达式):如果要删除的对象的静态类型与其动态类型不同,则静态类型应是要删除的对象的动态类型的基类,并且静态类型应具有虚析构函数或行为未定义。
静态类型(
base
)与动态类型(derv
)不同,静态类型没有虚析构函数,因此行为未定义。wztqucjr2#
在源代码中,没有内存泄漏,因为没有任何动态创建的成员变量。
考虑下面的修改示例情况1:
在这种情况下,输出将是,
在这种情况下,存在内存泄漏,因为'b'是使用'new'动态创建的,而'new'应该使用'delete'关键字删除。由于没有调用derv析构函数,所以它没有被删除,所以存在内存泄漏。
考虑以下情况2:
在情况2中输出将是,
在这种情况下,没有内存泄漏,因为调用了derv析构函数,b被删除了。
在基类中可以将析构函数定义为Virtual,以确保在删除指向派生类对象的基类指针时调用派生类析构函数。
我们可以说“当派生类有动态创建的成员时,析构函数必须是虚的”。
1wnzp6jl3#
加入讨论。如果你要求GCC对析构函数没有定义为虚拟函数的代码进行内存清理,GCC会抛出一个错误。你需要用
-fsanitize=地址
作为编译选项。
比如说,
编译时将输出以下错误
参见https://godbolt.org/z/aaTrovaPE
但是,如果你在base上声明了一个虚析构函数,那么错误就会消失。
nue99wik4#
代码中没有内存泄漏。如果您需要在派生类析构函数中释放一些内存,则会出现内存泄漏。