Consider the following:
In X.h:
class X
{
X();
virtual ~X();
};
X.cpp:
#include "X.h"
X::X()
{}
Try to build this (I'm using a .dll target to avoid an error on the missing main, and I'm using Visual Studio 2010):
Error 1 error LNK2001: unresolved external symbol "private: virtual __thiscall X::~X(void)" (??1X@@EAE@XZ)
Small modifications result in a successful build, however:
X.h:
class X
{
inline X(); // Now inlined, and everything builds
virtual ~X();
};
or
X.h:
class X
{
X();
~X(); // No longer virtual, and everything builds
};
What causes the unresolved external in the linker when the .dtor is virtual or when the .ctor isn't inlined?
EDIT:
Or, perhaps more interestingly, why do I not get an unresolved external if I make the destructor non-virtual, or if I inline the constructor?
So when we try to assign it a value in the main function, the linker doesn't find the symbol and may result in an “unresolved external symbol” or “undefined reference”. The way to fix this error is to explicitly scope the variable using '::' outside the main before using it.
A virtual destructor is used to free up the memory space allocated by the derived class object or instance while deleting instances of the derived class using a base class pointer object.
Deleting a derived class object using a pointer of base class type that has a non-virtual destructor results in undefined behavior.
Virtual keyword for destructor is necessary when you want different destructors should follow proper order while objects is being deleted through base class pointer.
You have the code for the constructor.
So it builds the constructor into the object file. The constructor needs the address of the destructor to put into the virtual table because it can not find it the constructor can not be built.
The compiler decides it does not need to build the constructor (as it will be inlined).
As such it does not plant any code and therefore does not need the address of the destructor.
If you instanciate an object of type X it will again complain.
You don't need the address of the destructor to build the constructor.
So it does not complain.
It will complain if you instantiate an object of type X.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With