I have an interface that represent ADT 'Bag'. To implement that abstract data type I used Array based and Linked based implementation.
Here the definition of class
edit As you indicated, i've added virtual destructor to my Base class
template<class ItemType>
class BagInterface{
public:
... some methods
~BagInterface();
};
#endif /* BagInterface_hpp */
And my 2 derived class implement these methods on their way.
My link based implementation is using virtual destructor because unlike array based implementation it's dynamically allocating memory and eventually it has to delete instance by using 'delete' keyword due to avoid from memory leaks.
destructor of linked bag
template<class ItemType>
LinkedBag<ItemType>::~LinkedBag(){
clear(); // Clears bag's content.
}
destructor of arraybag
template<class ItemType>
ArrayBag<ItemType>::~ArrayBag(){
clear();
}
I've created a function that takes a pointer as a input to represent bag in order to test my implementations.
void bagTester(BagInterface<int>* bagPtr){
// do some test }
I'd like to delete my derived class through base class pointers in the following.
int main() {
BagInterface<int>* bagPtr = nullptr; // base class pointer
char userChoice;
cin>> userChoice;
if(userChoice == 'A'){
bagPtr = new ArrayBag<int>(); // Array based implementation
}else if(userChoice == 'L'){
bagPtr = new LinkedBag<int>(); // Link based implementation
}
bagTester(bagPtr); // test my bag
delete bagPtr; // and now i'm finished with test let's delete the object
bagPtr = nullptr; // to avoid dangling pointers
}
In that point my error is occurring, compiler gives a warning ->
In file included from main.cpp:2:
In file included from ./LinkedBag.hpp:5:
./BagInterface.hpp:36:31: warning: defaulted function definitions are a C++11 extension [-Wc++11-extensions]
virtual ~BagInterface() = default;
^
In file included from main.cpp:4:
./ArrayBag.hpp:28:5: error: exception specification of overriding function is more lax than base version
~ArrayBag();
^
main.cpp:48:22: note: in instantiation of template class 'ArrayBag<int>' requested here
bagPtr = new ArrayBag<int>();
^
./BagInterface.hpp:36:13: note: overridden virtual function is here
virtual ~BagInterface() = default;
^
In file included from main.cpp:2:
./LinkedBag.hpp:25:1: error: exception specification of overriding function is more lax than base version
~LinkedBag();
^
main.cpp:52:22: note: in instantiation of template class 'LinkedBag<int>' requested here
bagPtr = new LinkedBag<int>();
^
./BagInterface.hpp:36:13: note: overridden virtual function is here
virtual ~BagInterface() = default;
^
1 warning and 2 errors generated.
So, how can I avoid from the warning?
Right now, when you run this code :
delete bagPtr;
the destructor from the link based implementation isn't called.
template<class ItemType>
class BagInterface{
public:
.....
virtual ~BagInterface() = default;
};
You need this destructor if you are going to delete a class derived from BagInterface through a pointer to BagInterface (or if a sharedpointer<BagInterface>
pointing to a derived class from BagInterface goes out of scope).
My link based implementation is using virtual destructor because unlike array based implementation it's dynamically allocating memory and eventually it has to delete instance by using 'delete' keyword due to avoid from memory leaks.
This is why you need a virtual destructor in your base class : if you don't have one, when you delete a derived class through a pointer of the base class, you get undefined behaviour.
Deleting an object through pointer to base invokes undefined behavior unless the destructor in the base class is virtual. source here