为什么需要虚析构函数?

3

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

#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文件中使用虚析构函数。从这里我们可以了解到,当您可以通过基类指针删除派生类的实例时,虚析构函数非常有用。但我认为这在这段代码中并不适用。有人能解释一下吗?


5
如果他们费尽心思定义一个虚析构函数,那是因为他们预期有人会创建一个以“SpectralClustering”为基类的派生类。 - Cory Kramer
3个回答

10

将析构函数声明为虚函数的原因是您打算将该类继承并以多态方式使用。 如果我们有

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

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

Foo的析构函数将被调用,Bar部分的对象成员将不会被销毁。如果Foo有一个虚析构函数,那么会发生vtable查找,Bar析构函数将被正确调用以销毁对象。


1

假定可以继承该类。否则,应使用final指定符进行声明。

请注意,该类的数据成员具有访问控制指定符protected。这意味着类的作者并不排除该类可以被继承。


0

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接