为什么虚拟析构函数?

时间:2015-08-19 11:50:20

标签: c++ inheritance virtual-destructor

我正在浏览一些代码,计划将其用于我的研究。所以头文件看起来像这样

#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文件中使用虚拟析构函数。从this我们可以了解到,当您可以通过指向基类的指针删除派生类的实例时,虚拟析构函数很有用。但我认为这不是这个代码的情况。有人可以解释这一切吗?

3 个答案:

答案 0 :(得分:7)

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

class Foo {};
class Bar : public Foo {};

Foo * f = new Bar();
delete f; // f's destructor is called here

将调用Foo的析构函数,并且不会销毁该对象的Bar部分的任何成员。如果Foo有一个虚拟析构函数,则会发生vtable查找,而不会正确地销毁Bar析构函数。

答案 1 :(得分:1)

假设该类可以继承。否则,应使用说明符final声明它。

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

答案 2 :(得分:0)

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

框架的用户可以以这种方式定制框架,而无需直接更改框架代码。所以,可能有一种方法可以使用派生类而不是原始的SpectralClustering类,或者甚至代替任何类SpectralClustering派生的(不是在这种情况下,因为它不是从任何东西)。该框架很可能是使用基类引用删除实例,而实际的实现是派生的。