📜  C++中的纯虚拟析构函数(1)

📅  最后修改于: 2023-12-03 14:39:58.863000             🧑  作者: Mango

C++中的纯虚拟析构函数

在C++中,析构函数是类的特殊成员函数,负责在对象销毁时释放资源。如果一个类需要被继承,我们通常会把析构函数声明成虚拟函数,以确保派生类的析构函数能够正确调用。不过,如果我们希望基类不能被实例化,同时又希望在销毁派生类对象时可以正确调用基类析构函数,我们可以使用纯虚拟析构函数。

纯虚拟析构函数的定义

定义纯虚拟析构函数的方法与定义普通的纯虚拟函数类似,只需要在函数声明后加上“= 0”即可:

class Base {
public:
    virtual ~Base() = 0;
};

Base::~Base() {}

需要注意的是,纯虚拟析构函数必须有定义,在实现文件中需要给出函数实现。

纯虚拟析构函数的作用

纯虚拟析构函数的主要作用是,防止用户直接实例化基类对象,同时在销毁派生类对象时,能够正确地调用基类析构函数。例如,我们定义一个抽象类Shape,用于表示图形的基本属性和方法:

class Shape {
public:
    virtual double area() const = 0;
    // ...
};

由于Shape类是抽象类,不能被实例化,但可以被继承。如果我们没有定义纯虚拟析构函数,那么在销毁Shape派生类对象时,可能会导致内存泄漏。

Shape* shape = new Circle(1.0);
delete shape; // 不能正确地调用Circle的析构函数

而如果我们定义了纯虚拟析构函数,就可以保证在销毁Shape派生类对象时,能够正确地调用基类析构函数。

class Shape {
public:
    virtual ~Shape() = 0;
    virtual double area() const = 0;
};

Shape::~Shape() {}

class Circle : public Shape {
public:
    virtual double area() const override {
        return radius_ * radius_ * 3.1415926;
    }
private:
    double radius_;
};

Shape* shape = new Circle(1.0);
delete shape; // 正确地调用Circle和Shape的析构函数
总结

纯虚拟析构函数可以防止用户直接实例化基类对象,并且能够正确地调用基类析构函数,是一种很有用的C++语言特性。但需要注意的是,纯虚拟析构函数必须有定义,否则会出现链接错误。