为什么是虚析构函数

Why virtual destructor?

本文关键字:析构函数 为什么      更新时间:2023-10-16

我正在浏览一些代码,计划将其用于我的研究。头文件是这样的

#ifndef SPECTRALCLUSTERING_H_
#define SPECTRALCLUSTERING_H_
#include <vector>
#include <eigen3/Eigen/Core>
class SpectralClustering {
public:
    SpectralClustering(Eigen::MatrixXd& data, int numDims);
    virtual ~SpectralClustering();
    std::vector<std::vector<int> > clusterRotate();
    std::vector<std::vector<int> > clusterKmeans(int numClusters);
    int getNumClusters();
protected:
    int mNumDims;
    Eigen::MatrixXd mEigenVectors;
    int mNumClusters;
};
#endif /* SPECTRALCLUSTERING_H_ */

主代码后面的

#include "SpectralClustering.h"
#include <eigen3/Eigen/QR>
SpectralClustering::SpectralClustering(Eigen::MatrixXd& data, int numDims):
    mNumDims(numDims),
    mNumClusters(0)

所以我不明白为什么在。h文件中使用虚拟析构函数。从这里我们可以了解到,当您可以通过基类指针删除派生类的实例时,虚析构函数非常有用。但我认为这段代码不是这样的。有人能解释一下这一切吗?

将析构函数设置为虚函数的原因是您计划以多态方式继承和使用该类。如果我们有

class Foo {};
class Bar : public Foo {};
Foo * f = new Bar();
delete f; // f's destructor is called here

将调用Foo的析构函数,并且不会取消对象Bar部分的成员。如果Foo有虚析构函数,那么虚函数表查找将发生,Bar析构函数将被调用,而不是正确地销毁对象。

假定这个类可以被继承。否则,应该使用说明符final来声明。

考虑类的数据成员具有访问控制说明符protected。这意味着类的作者不排除该类可以被继承。

代码可能是以这样一种方式编写的,即通过派生自定义类来定制类实现是支持的。

框架的用户可以用这种方式自定义框架,而不需要直接修改框架代码。因此,可能有一种方法可以使用您的派生类来代替原始的SpectralClustering类,甚至代替SpectralClustering派生的任何类(不是在这种情况下,因为它不派生任何东西)。框架很可能会删除使用基类引用的实例,而实际的实现是派生的。