#include <iostream>
#include <vector>
class Shape {
public:
static int createOrder;
static int destroyOrder;
int myCreateOrder;
int myDestroyOrder;
Shape() {
myCreateOrder = ++createOrder;
std::cout << "Shape created, order: " << myCreateOrder << std::endl;
}
virtual ~Shape() {
myDestroyOrder = ++destroyOrder;
std::cout << "Shape destroyed, order: " << myDestroyOrder << std::endl;
}
virtual void draw() const = 0;
};
int Shape::createOrder = 0;
int Shape::destroyOrder = 0;
class Circle : public Shape {
public:
Circle() {
std::cout << "Circle created, order: " << myCreateOrder << std::endl;
}
~Circle() {
std::cout << "Circle destroyed, order: " << myDestroyOrder << std::endl;
}
void draw() const override {
std::cout << "Drawing a Circle" << std::endl;
}
};
class Rectangle : public Shape {
public:
Rectangle() {
std::cout << "Rectangle created, order: " << myCreateOrder << std::endl;
}
~Rectangle() {
std::cout << "Rectangle destroyed, order: " << myDestroyOrder << std::endl;
}
void draw() const override {
std::cout << "Drawing a Rectangle" << std::endl;
}
};
void operateOnShape(Shape* shape) {
shape->draw();
}
int main() {
std::vector<Shape*> shapes;
shapes.push_back(new Circle());
shapes.push_back(new Rectangle());
for (Shape* shape : shapes) {
operateOnShape(shape);
}
for (Shape* shape : shapes) {
delete shape;
}
return 0;
}
为什么要在基类使用虚析构函数
- 防止内存泄漏:当通过基类指针删除派生类对象时,如果基类析构函数不是虚函数,那么只会调用基类的析构函数,派生类的析构函数不会被调用。这会导致派生类中分配的资源无法被释放,从而造成内存泄漏。例如在上述代码中,如果
Shape
的析构函数不是虚函数,delete shape
时,只会调用Shape
的析构函数,Circle
和Rectangle
的析构函数不会被调用。
- 实现多态析构:虚析构函数确保了在通过基类指针删除对象时,能够调用正确的(即派生类的)析构函数。这是多态性在析构过程中的体现,保证了对象的完整销毁,释放所有分配的资源。