Why virtual destructor?

2019-08-09 01:03发布

问题:

I am going through some code,plan to adapt it for my research.So header file looks like this

#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_ */

Latter in the main code

#include "SpectralClustering.h"
#include <eigen3/Eigen/QR>

SpectralClustering::SpectralClustering(Eigen::MatrixXd& data, int numDims):
    mNumDims(numDims),
    mNumClusters(0)

So I do not understand why virtual destructor was used in the .h file. From this we can learn that virtual destructors are useful when you can delete an instance of a derived class through a pointer to base class.But I think this is not case with this code.Can someone explain all this?

回答1:

The reason you would make a destructor virtual is that you plan for that class to be inherited and used polymorphicly. If we had

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

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

The destructor for Foo would be called and no members of the Bar part of the object would be destroyed. If Foo had a virtual destructor then a vtable lookup would happen the the Bar destructor would be called instead correctly destroying the object.



回答2:

It is supposed that the class can be inherited. Otherwise it should be declared with specifier final.

Take into account that data members of the class have access control specifier protected. It means that the author of the class does not exclude that the class can be inherited.



回答3:

The code was probably written in such a way, that customizing the class implementations by deriving custom classes is supported.

The user of the framework can customize the framework in that way without the need to change the framework code directly. So, probably there is a way to use your derived class in stead of the original SpectralClustering class, or even in stead of any class SpectralClustering derives from (not in this case, as it does not derive from anything). The framework may very well be deleting instances using base class references, while the actual implementation is derived.