在C++中,基类的析构函数默认是非虚的。如果基类有一个非虚的析构函数,当通过基类的指针删除派生类的对象时,会发生未定义行为。这是因为非虚析构函数不能保证在删除派生类对象时,基类的析构函数被调用后,派生类的析构函数也得到调用。
这里有一个例子来说明这个问题:
```cpp
class Base {
public:
~Base() {
// 基类的析构函数
}
};
class Derived : public Base {
public:
~Derived() {
// 派生类的析构函数
}
};
int main() {
Base* basePtr = new Derived();
delete basePtr; // 未定义行为,因为Base的析构函数是非虚的
return 0;
}
```
在上面的代码中,`Base` 类的析构函数不是虚函数。当我们创建一个 `Derived` 类型的对象,并通过 `Base` 类型的指针删除它时,只有 `Base` 类的析构函数会被调用,而 `Derived` 类的析构函数则不会。这可能导致资源泄漏或其他问题,因为 `Derived` 类的析构函数中可能包含清理资源的代码。
为了避免这种情况,应该将基类的析构函数声明为虚函数:
```cpp
class Base {
public:
virtual ~Base() {
// 基类的析构函数
}
};
```
这样,当通过基类的指针删除派生类的对象时,C++ 运行时会确保首先调用派生类的析构函数,然后调用基类的析构函数,从而保证资源的正确释放和对象的完全析构。