让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如果还有疑问可以评论或留言问题解答: 在派生类中如果没有显式地定义析构函数,那么会默认调用基类的析构函数。但是如果派生类中有动态分配的资源,如果不手动释放的话,就会导致内存泄漏。所以为了解决这个问题,C++中引入了虚析构函数的概念。 虚析构函数就是可以实现基类指针可以指向派生类对象,并通过基类指针释放动态分配的内存空间。在基类中定义虚析构函数,通过多态性让派生类释放空间时首先调用析构函数,再释放空间。 所以,在 Base *b=new Derived() 的情况下,使用了派生类的名称,是因为通过继承,派生类拥有了基类中的成员变量和成员函数。而在这个例子中,如果派生类中有动态分配的资源需要手动释放,那么需要用到析构函数,因此定义虚析构函数让基类指针可以指向派生类对象,并通过基类指针释放动态分配的内存空间。 举个例子,假设有一个基类`Animal`和一个派生类`Cat`,其中`Cat`定义了动态分配的资源。如果没有虚析构函数,那么在释放`Cat`对象时会出现内存泄漏。代码如下:
class Animal {
public:
virtual void move() {
cout << "Animal move" << endl;
}
};
class Cat : public Animal {
public:
Cat() {
p = new int(10);
}
void move() {
cout << "Cat move" << endl;
}
~Cat() {
cout << "Cat destructor" << endl;
delete p;
}
private:
int *p;
};
int main() {
// 使用普通指针释放空间
Animal *a = new Cat();
delete a; // 只会调用基类的析构函数,导致Cat的析构函数没有被调用,从而产生内存泄漏
return 0;
}
而如果定义虚析构函数,就可以避免这个问题,代码如下:
class Animal {
public:
virtual void move() {
cout << "Animal move" << endl;
}
virtual ~Animal() {
cout << "Animal destructor" << endl;
}
};
class Cat : public Animal {
public:
Cat() {
p = new int(10);
}
void move() {
cout << "Cat move" << endl;
}
~Cat() {
cout << "Cat destructor" << endl;
delete p;
}
private:
int *p;
};
int main() {
// 使用基类指针释放空间,保证调用派生类的析构函数
Animal *a = new Cat();
delete a;
return 0;
}
输出结果:
Cat destructor
Animal destructor
