Why virtual destructor? - c++

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?

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.

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.

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.

Related

Why doesn't derived templated class's function override the non-templated base class's pure virtual function?

#include <vector>
class Base
{
public:
virtual void foo() = 0;
};
template<typename Bar>
class Cloud : public Base
{
public:
void foo()
{
}
};
class Water
{
};
int main()
{
Cloud<Water> cloud;
std::vector<Base> stuff;
stuff.push_back(cloud);
}
The above shown code fails with the following on MSVC 14.1:
error C2259: 'Base': cannot instantiate abstract class
note: due to following members:
note: 'void Base::foo(void)': is abstract
Why does Base::foo() remain abstract even though Cloud implements it?
How would I implement this in a way that Cloud still derives from Base, overrides foo() and remains templated with typename Bar?
The function is a red herring: std::vector<Base> is a vector of Base objects, hence push_back tries to construct a Base from your Cloud<Water>.
Use a std::vector<std::unique_ptr<Base>> instead.
Templates here are just a distraction - they have nothing to do with your problem.
std::vector<Base> contains Base objects, not references, so if you try to add any derived instance to it, it will try to perform slicing, trying to instantiate a Base from the passed cloud. This, however, besides not being what you probably intended, is not possible, since a straight Base object cannot exist due to Base being an abstract class.
Most probably what you wanted was to push your object in the vector while still keeping the polymorphic behavior. To this end, you have to have a vector of pointers to the base class, and push pointers to the elements - most probably allocated on the heap, and with some mean of handling their lifetime. A simple (albeit possibly not optimal) solution may be having a std::vector<std::shared_ptr<Base>> and push objects allocated with std::make_shared.

Accessing base class elements without breaking encapsulation

I have created two classes A and B where B inherits from class A. As you can see, I have a vector in class A that is currently under the protected section of the class. I am unsure if using protected is bad practice?
#include <vector>
class A
{
public :
A();
protected:
std::vector <std::string> a;
};
class B : A
{
public :
B();
void accessVector()
{
a.size();
}
private:
};
When A makes a data member a protected, it is offering the following guarantee to all classes that derive from it:
"You may do anything you like to a without telling me. This includes appending to it, modifying its contents, removing items, sorting it, moving from it, moving to it and otherwise making its state undefined and/or unknowable to me".
Remember that anyone may create a class that derives from A.
For this reason, to all intents and purposes, a protected member is a public member, since a derived class may simply say the following:
public:
using A::a;
Starting here and working forward, you'll find that there are only two sensible use-cases for protected:
When a base class defines a virtual member function that may need to be called from an overridden version of the same function in a derived class.
When the base class wants to expose 'data as interface' to a derived class, but not to the world.

Protected constructor to make base class not instantiable

Is it good practice to make a base class constructor protected if I want to avoid instances of it? I know that I could as well have a pure virtual dummy method, but that seems odd...
Please consider the following code:
#include <iostream>
using std::cout;
using std::endl;
class A
{
protected:
A(){};
public:
virtual void foo(){cout << "A\n";};
};
class B : public A
{
public:
void foo(){cout << "B\n";}
};
int main()
{
B b;
b.foo();
A *pa = new B;
pa->foo();
// this does (and should) not compile:
//A a;
//a.foo();
return 0;
}
Is there a disadvantage or side-effect, that I don't see?
It is common practice to make base class constructors protected. When you have a pure-virtual function in your base class, this is not required, as you wouldn't be able to instantiate it.
However, defining a non-pure virtual function in a base class is not considered good practice, but heavily depends on your use case and does not harm.
There isn't any disadvantage or side-effect. With a protected constructor you just tell other developers that your class is only intended to be used as a base.
What you want to achieve is normally done via the destructor, instead of the constructors, just beacause you can steer the behavior you need with that one function instead of having to deal with it with every new constructor you write. It's a common coding style/guideline, to
make the destructor public, if you want to allow instances of the class. Often those classes are not meant to be inherited from.
make the destructor pure virtual and public, if you want to use and delete the class in a polymorphic context but don't want to allow instances of the class. In other words, for base classes that are deleted polymorphcally.
make the destructor nonvirtual and protected, if you don't want to allow instances of the class and don't want to delete its derivates polymorphically. Normally, you then don't want to use them polymorphically at all, i.e. they have no virtual functions.
Which of the latter two you chose is a design decision and cannot be answered from your question.
It does what you're asking.
However I'm not sure what you are gaining with it. Someone could just write
struct B : A {
// Just to workaround limitation imposed by A's author
};
Normally it's not that one adds nonsense pure-virtual functions to the base class... it's that there are pure virtual functions for which no meaningful implementation can be provided at the base level and that's why they end up being pure virtual.
Not being able to instantiate that class comes as a nice extra property.
Make the destructor pure virtual. Every class has a destructor, and a base class should usually have a virtual destructor, so you are not adding a useless dummy function.
Take note that a pure virtual destructor must have a function body.
class AbstractBase
{
public:
virtual ~AbstractBase() = 0;
};
inline AbstractBase::~AbstractBase() {}
If you don't wish to put the destructor body in the header file, put it in the source file and remove inline keyword.

Explicitly declaring abstract base class

Is there a way to explicitly declare a base class as abstract in C++?
I know that I can create a pure virtual function in the class which will implicitly declare a class as abstract. However, I don't want to have to create a dummy function just to define in in derived classes.
I could also make the constructor protected, which would prevent the instantiation of the object, but that doesn't actually mark the class as abstract.
So, is there a way to do this? (I am using C++11, if that added a way to do this, but I didn't find anything that looked right)
You can make the destructor pure-virtual. Since you always need a destructor, there's no additional mental cost:
struct Foo
{
virtual ~Foo() = 0;
};
inline Foo::~Foo() { }
(You do of course need an implementation of the destructor, so you have to provide one out-of-line.)
You can still make the destructor protected, which is good practice following the "make non-leaf classes abstract" rule.
Example:
struct Bar : Foo { };
// Foo f; // Error, Foo is abstract
Bar b; // OK
I like Kerrek's answer. That way the class cannot be instantiated and therefore is abstract.
However, it still isn't obviously clear that the class is abstract unless you scan through the entire declaration of the class and see that the destructor is virtual.
Another idea I had is you could create a pre-processor definition for the word "abstract" using #define. This way you could do something like the following:
abstract struct Foo {};
which would be no different than
struct Foo {};
The problem I see with this is that this doesn't force the class to be abstract, so you could use a macro to also declare the virtual destructor. Something like:
#define ABSTRACT_CLASS(class_name) \
class class_name { \
virtual ~class_name() = 0; //
And then use it like so:
ABSTRACT_CLASS(Foo) {
// class declaration
};
Which would be turned into:
class foo {
virtual ~class_name() = 0; // {
// class declaration
};
Disclaimer: My macro might be slightly off. I'm not sure if it'll actually paste class_name with the ~ and the () touching the variable name. Also, I'm not sure if I'd do this myself, it's not the most beautiful solution, especially commenting out the brace since that wouldn't work if you put it on the next line. But you asked how you could mark something as abstract and I gave it to you!
Is there a way to explicitly declare a base class as abstract in C++?
No, there is not. A class is abstract only if it has at least one abstract method declared in it. If you do not want your base class to be instantiated directly, then a protected constructor is a good choice.

How to call a derived class method from a base class method within the constructor of base

I am wondering if it is possible to call a derived class´ function from within a function called by the base constructor (shouldn´t it already be created when the code in the brackets are executed?)
#pragma once
class ClassA
{
public:
ClassA(void);
virtual ~ClassA(void);
void Init();
protected:
short m_a;
short m_b;
virtual void SetNumbers(short s);
};
include "ClassA.h"
#include <iostream>
ClassA::ClassA(void) : m_a(0), m_b(0)
{
Init();
}
ClassA::~ClassA(void)
{
}
void ClassA::SetNumbers(short s)
{
std::cout << "In ClassA::SetNumbers()\n";
m_a = s;
m_b = s;
}
void ClassA::Init()
{
this->SetNumbers(2);
}
#pragma once
#include "ClassA.h"
class ClassB : public ClassA
{
public:
ClassB(void);
virtual ~ClassB(void);
virtual void SetNumbers(short);
int x;
};
#include "ClassB.h"
#include <iostream>
ClassB::ClassB(void)
{
}
ClassB::~ClassB(void)
{
}
void ClassB::SetNumbers(short s)
{
std::cout << "In ClassB::SetNumbers()\n";
m_a = ++s;
m_b = s;
ClassA::SetNumbers(s);
}
Any suggestions how to do it?...
Thank You in advance :)...
No. All parts of B (starting with A, as it's base) are constructed before B's constructor is called. So, by the time SetNumbers is called, no part of B (except for the A part) has been constructed --- and that may include the v-table, so there's no way to know where that call is going to go.
Of course, there is a simple solution to this: Call B::SetNumber() from within B's constructor (That is, after all, the purpose of B's constructor)
You can't do this for the simple logical reason that while the base class is being constructed, the derived class hasn't even begun to be constructed. You can't call a member function on an object that doesn't exist (yet).
In practice, even if you managed to call SetNumbers and assign to the member variables of the derived class before they were initialized they would surely be overwritten when they finally get initialized. I admit it's a bit pointless to reason about this as we would be well outside defined behaivour.
No, sorry. :( It might compile in one or two C++ compilers, but it's not recommended. From the C++ FAQ Lite section 10.7:
[10.7] Should you use the this pointer
in the constructor?
[...snip...]
Here is something that never works:
the {body} of a constructor (or a
function called from the constructor)
cannot get down to a derived class by
calling a virtual member function that
is overridden in the derived class. If
your goal was to get to the overridden
function in the derived class, you
won't get what you want. Note that you
won't get to the override in the
derived class independent of how you
call the virtual member function:
explicitly using the this pointer
(e.g., this->method()), implicitly
using the this pointer (e.g.,
method()), or even calling some other
function that calls the virtual member
function on your this object. The
bottom line is this: even if the
caller is constructing an object of a
derived class, during the constructor
of the base class, your object is not
yet of that derived class. You have
been warned.
NOTE: Emphasis mine.
More details at the link
The only time you can do this is when something is derived from a template that is parameterised by itself:
template<typename T> class base
{
T* down_cast() throw()
{
return static_cast<Derived*>(this);
}
const T* down_cast() const throw()
{
return static_cast<const Derived*>(this);
}
public:
base()
{
down_cast()->doSomething();
}
/* … */
};
class derived : private base<derived>
{
public:
void doSomething()
{
}
};
Note that doSomething is public and not virtual.
We can static_cast to derived, because it's known that derived is the derived type.
Deriving something from a base parameterised by itself is a strange thing to be doing at the best of times. It's said that when the ATL team in microsoft used it they asked the C++ compiler team if it was valid and nobody was sure, though it is valid because template construction depends on names as follows:
First the template is available, but not used in a class. Then, the name derived available. Then it instantiates the layout of base<derived> — this requires knowledge of the member variables and virtual functions, as long as none of that depends upon knowledge of derived’s layout (pointers and references are fine) this will all go okay. Then it will create the layout of derived, and finally it will create derived’s member functions, which may include creating member functions for base<derived>. So as long as base<derived> doesn’t contain a derived member variable (base classes can never contain a member variable of a type derived from themselves) or a virtual function that requires knowledge of derived’s layout we can indeed do the dicey-looking piece of inheritance above.
This includes being able to call non-virtual public members of derived from base during construction, because it's already part of base. There are strong limitations on this. In particular, if doSomething() depends on anything constructed in derived's constructor it won't work as derived hasn't been constructed yet.
Now, is this actually a good idea? No.
A simple design solution is to use aggregation instead of inheritance.