C++ virtual functions.Problem with vtable [duplicate] - c++

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
GCC C++ Linker errors: Undefined reference to 'vtable for XXX', Undefined reference to 'ClassName::ClassName()'
I'm doing a little project in C++ and I've come into some problems regarding virtual functions.
I have a base class with some virtual functions:
#ifndef COLLISIONSHAPE_H_
#define COLLISIONSHAPE_H_
namespace domino
{
class CollisionShape : public DominoItem
{
public:
// CONSTRUCTOR
//-------------------------------------------------
// SETTERS
//-------------------------------------------------
// GETTERS
//-------------------------------------------------
virtual void GetRadius() = 0;
virtual void GetPosition() = 0;
virtual void GetGrowth(CollisionShape* other) = 0;
virtual void GetSceneNode();
// OTHER
//-------------------------------------------------
virtual bool overlaps(CollisionShape* shape) = 0;
};
}
#endif /* COLLISIONSHAPE_H_ */
and a SphereShape class which extends CollisionShape and implements the methods above
/* SphereShape.h */
#ifndef SPHERESHAPE_H_
#define SPHERESHAPE_H_
#include "CollisionShape.h"
namespace domino
{
class SphereShape : public CollisionShape
{
public:
// CONSTRUCTOR
//-------------------------------------------------
SphereShape();
SphereShape(CollisionShape* shape1, CollisionShape* shape2);
// DESTRUCTOR
//-------------------------------------------------
~SphereShape();
// SETTERS
//-------------------------------------------------
void SetPosition();
void SetRadius();
// GETTERS
//-------------------------------------------------
void GetRadius();
void GetPosition();
void GetSceneNode();
void GetGrowth(CollisionShape* other);
// OTHER
//-------------------------------------------------
bool overlaps(CollisionShape* shape);
};
}
#endif /* SPHERESHAPE_H_ */
and the .cpp file:
/*SphereShape.cpp*/
#include "SphereShape.h"
#define max(a,b) (a>b?a:b)
namespace domino
{
// CONSTRUCTOR
//-------------------------------------------------
SphereShape::SphereShape(CollisionShape* shape1, CollisionShape* shape2)
{
}
// DESTRUCTOR
//-------------------------------------------------
SphereShape::~SphereShape()
{
}
// SETTERS
//-------------------------------------------------
void SphereShape::SetPosition()
{
}
void SphereShape::SetRadius()
{
}
// GETTERS
//-------------------------------------------------
void SphereShape::GetRadius()
{
}
void SphereShape::GetPosition()
{
}
void SphereShape::GetSceneNode()
{
}
void SphereShape::GetGrowth(CollisionShape* other)
{
}
// OTHER
//-------------------------------------------------
bool SphereShape::overlaps(CollisionShape* shape)
{
return true;
}
}
These classes, along some other get compiled into a shared library.
Building libdomino.so
g++ -m32 -lpthread -ldl -L/usr/X11R6/lib -lglut -lGLU -lGL -shared -lSDKUtil -lglut -lGLEW -lOpenCL -L/home/adrian/AMD-APP-SDK-v2.4-lnx32/lib/x86 -L/home/adrian/AMD-APP-SDK-v2.4-lnx32/TempSDKUtil/lib/x86 -L"/home/adrian/AMD-APP-SDK-v2.4-lnx32/lib/x86" -lSDKUtil -lglut -lGLEW -lOpenCL -o build/debug/x86/libdomino.so build/debug/x86//Material.o build/debug/x86//Body.o build/debug/x86//SphereShape.o build/debug/x86//World.o build/debug/x86//Engine.o build/debug/x86//BVHNode.o
When I compile the code that uses this library I get the following error:
../../../lib/x86//libdomino.so: undefined reference to `vtable for domino::CollisionShape'
../../../lib/x86//libdomino.so: undefined reference to `typeinfo for domino::CollisionShape'
Command used to compile the demo that uses the library:
g++ -o build/debug/x86/startdemo build/debug/x86//CMesh.o build/debug/x86//CSceneNode.o build/debug/x86//OFF.o build/debug/x86//Light.o build/debug/x86//main.o build/debug/x86//Camera.o -m32 -lpthread -ldl -L/usr/X11R6/lib -lglut -lGLU -lGL -lSDKUtil -lglut -lGLEW -ldomino -lSDKUtil -lOpenCL -L/home/adrian/AMD-APP-SDK-v2.4-lnx32/lib/x86 -L/home/adrian/AMD-APP-SDK-v2.4-lnx32/TempSDKUtil/lib/x86 -L../../../lib/x86/ -L"/home/adrian/AMD-APP-SDK-v2.4-lnx32/lib/x86"
(the -ldomino flag)
And when I run the demo, I manually tell it about the library:
LD_LIBRARY_PATH=../../lib/x86/:$AMDAPPSDKROOT/lib/x86:$LD_LIBRARY_PATH bin/x86/startdemo
After reading a bit about virtual functions and virtual tables I understood that virtual tables are handled by the compiler and I shouldn't worry about it, so I'm a little bit confused on how to handle this issue.
I'm using gcc version 4.6.0 20110530 (Red Hat 4.6.0-9) (GCC)
Later edit:
I'm really sorry, but I wrote the code by hand directly here.
I have defined the return types in the code.
I apologize to the 2 people that answered below.
I have to mention that I am a beginner at using more complex project layouts in C++.By this I mean more complex makefiles, shared libraries, stuff like that.
My problem was caused by the fact that I didn't define the body of virtual void CollisionShape::GetSceneNode().
The way to fix this is to either define the above function, or declare it as pure virtual as such:
virtual void CollisionShape::GetSceneNode() = 0;

Any non-pure virtual function must be defined, even if it's never used. A missing definition will often result in the 'vtable undefined' linker error, especially when the very first non-pure, non-inline virtual function of a class is left undefined. In your case, CollisionShape::GetSceneNode() is left undefined.
On an unrelated note, every class that has a virtual function needs a virtual destructor, every time, absolutely no exceptions whatsoever. The language unfortunately doesn't enforce this, so it's your responsibility. G++ has a flag, -Weffc++, which enables warnings for this and other common pitfalls, described in the Scott Meyers's book "Effective C++". I strongly recommend using this flag all the time. Using -Werror by default is also a good habit. Suppress individual warnings one by one, and only if there's no possibility to fix the code.

I can't say for certain whether this will fix your compilation error, but in any case you need to declare a virtual destructor (virtual ~CollisionShape()) in your CollisionShape class. Failure to do so will result in undefined runtime behavior when SphereShape is deleted through its base class pointer (a pointer to CollisionShape). Of course, since a virtual constructor is indeed added to a class's vtbl, I guess it's not beyond the realm of possibility that this is the culprit behind your error.
In Effective C++, Scott Meyers has the following to say.
The C++ language standard is unusually clear on this topic. When you try to delete a derived class object through a base class pointer and the base class has a nonvirtual destructor [...], the results are undefined. That means compilers may generate code to do whatever they like: reformat your disk, send suggestive mail to your boss, fax source code to your competitors, whatever. (What often happens at runtimme is that the derived class's destructor is never called. [...])

Due to the conflicting declarations of GetSceneNode, in your current code
virtual void GetSceneNode();
in the base class, and
SceneNode* GetSceneNode();
in the derived class, your code should not compile. You should not get to the linking stage. I'm pretty sure that the code that you're presenting is not your real code.
Hence, I downvoted the question.
But regarding the error that you evidently produced with some other code, it has been asked before on SO, and answered for example here.
Hence, I also voted to close the question.
Cheers & hth.,

This may not be the whole problem, but you are missing a return type on those functions. ie
virtual double GetPosition() = 0;

Related

c++ undefined reference to vtable exception [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I've searched many answers but none of them can solve my problem, I'm new to c++, this issue is quite wired to me. Below is a simplified extraction of my code.
TestHeader.h:
#ifndef NAMESPACE_TESTHEADER_H_
#define NAMESPACE_TESTHEADER__H_
namespace Namespace {
class TestHeader {
public:
TestHeader(const std::string& str) : anyString_(str) { }
virtual std::string methodOne(const std::string& param) const;
virtual ~TestHeader() { anyString_.clear(); }
protected:
std::string anyString_;
};
}
#endif //NAMESPACE_TESTHEADER__H_
TestHeader.cpp:
#include "TestHeader.h"
using namespace std;
namespace Namespace {
TestHeader::TestHeader(const std::string& str):anyString_(str) { <do something>; }
std::string TestHeader::methodOne(const std::string& param) const
{
return <A string>;
}
TestHeader::~TestHeader() {
anyString_.clear();
}
}
What I did was simply call this line in any other .cpp in my package:
#include "TestHeader.h"
TestHeader testHeader("whatever");
The build failed by throwing
error: undefined reference to 'vtable for Namespace::TestHeader'
the vtable symbol may be undefined because the class is missing its key function
The most weird thing is: if I comment out virtual std::string methodOne(const std::string& str) const; in header and its implementation in .cpp, OR, if I comment out : anyString_(str) after constructor and anyString_.clear(); in destructor together in header only, the build will succeed.
Firstly You should not define the constructor and destructor twice. It shouldn't be compiling as mentioned by Curious in comments
Second I assume that you want don't the class to be abstract as there is no Runtime polymorphism implemented which is the basic use of Virtual functions.
If you don't want the class TestHeader to be abstract remove the virtual keyword which is referring to Virtual Table.C++ compiler inserts Virtual Table for every class having virtual function or class inherited from the class that has virtual functions.
Better study the use of Virtual keyword and then write the code.
Here are quick links for the same
Link 1
Link 2
Also, I think you need to revisit few concepts from Destructor virtual ~TestHeader() { anyString_.clear(); } does not make any sense. In fact, there is no base class which in turn denies the use of Virtual Destructor which is used in case of Inheritance
Firstly, include #include <string> at the top of your header file. I am guessing the error is because you have not linked the object file produced after compiling TestHeader.cpp with the source file that contains the declaration and initialization for the variable named testHeader
Compile these with the following command and you should see a linker error that complains saying that you have multiple definitions for the constructor
g++ -std=c++14 TestHeader.cpp yourfile.cpp
After you see those errors, remove the multiple definitions, either put all your definitions in the cpp file or only put them in one place and then recompile and link with the above command. The linker error should be gone.

C++ linker warning because of virtual destructor / clang

I'm getting a linker warning caused by virtual destructors. My environment is the KEIL compiler v6.5 (clang).
Warning: L6439W: Multiply defined Global Symbol __clang_call_terminate defined in invalid_group(new.cpp.o) rejected in favor of Symbol defined in .text.__clang_call_terminate(cxa_handlers.cpp.o).
I get this warning as soon as I add the virtual destructor to an interface. For example:
class IInterface {
virtual ~IInterface(){}
virtual void doSomething() const = 0;
}
As soon as I implement one single derived class of this interface I get the above mentioned warning. As soon as I remove the virtual destructor, the warning vanishes.
I tried really many things to find out what's the reason, but didn't succeed...
Does someone know how to fix this warning?
Thank you!
Edit: A complete example throwing this warning:
class IInterface {
public:
virtual ~IInterface();
virtual void doSomething() = 0;
};
IInterface::~IInterface() {
}
class SomeClass : public IInterface {
public:
virtual void doSomething();
};
void SomeClass::doSomething() {
}
int main() {
}
I asked support of ARM and got the information that this warning is spurious. So it seems to be an issue of the current ARM clang compiler toolchain implementation.
Nevertheless thank you all for your responses on this topic.
If you define your function in header you will emit the function each time you include it in a file. To remove this warming you need to define your method outside the declaration
// IInterface.hpp
class IInterface {
public:
virtual ~IInterface();
}
// IInterface.cpp
IInterface::~IInterface() {}
As mentioned, this was a linker bug which has been fixed in ARM Compiler v6.11 (10/25/2018).
Release notes:
[SDCOMP-30157] In certain circumstances, after discarding a section from a COMDAT ELF section group, the linker could incorrectly report Warning: L6439W: Multiply defined Global Symbol defined in invalid_group() rejected in favour of Symbol defined in (). This has been fixed.

"Allocating an object of abstract class type" error although all functions have implementations

I know questions about this error have been asked repeatedly, however none of the previous answers seem to solve my problem.
I have a pure abstract class ITile:
class ITile {
public:
virtual ~ITile() {}
virtual void display() = 0;
virtual bool isWalkable() = 0;
virtual bool isGoal() = 0;
};
And three subclasses that all implement these functions like so:
Floor.h
#include "ITile.h"
class Floor : public ITile {
public:
Floor();
virtual ~Floor();
virtual void display() override;
virtual bool isWalkable() override;
virtual bool isGoal() override;
};
Floor.cpp
#include "Floor.h"
#include <iostream>
using namespace std;
Floor::Floor() {}
Floor::~Floor() {}
void Floor::display() {
cout << " ";
}
bool Floor::isWalkable() {
return true;
}
bool Floor::isGoal() {
return false;
}
When trying to compile the whole project I get the following output:
g++ -std=c++0x -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/main.d" -MT"src/main.d" -o "src/main.o" "../src/main.cpp"
In file included from ../src/main.cpp:1:
In file included from ../src/board.h:1:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:265:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/__bit_reference:15:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/algorithm:627:
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:1641:31: error: allocating an object of abstract class type 'ITile'
::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
[...]
...followed by a bunch of notes. But the problem is, I guess, the error in the last line above.
So, what exactly are these algorithm, memory files and so on? How can I get rid of this error?
I'm using Eclipse Luna with the C/C++ plugin on Mac OS X (Mavericks) with the Developer Command Line Tools. Any more info gladly given upon request.
Thanks in advance!
You can't declare a std::vector<ITile>, because ITiles cannot exist.
In order to make use of polymorphism in a container, you'll need to store pointers. Those pointers will point to dynamically-allocated objects of type Floor, Wall, Ceiling… whatever else you've got.
Consider a std::vector<std::unique_ptr<ITile>>.
ITile is an abstract class.
For pre C++11 compilers, you cannot create a std::vector<ITile>. std::vector can be used only with types that are CopyConstructible and CopyAssignable. An abstract class is neither CopyConstructible nor CopyAssignable.
If you are using a C++11, or later, compiler the type need not be CopyConstructible and CopyAssignable to construct a std::vector. Other member functions may impose those requirements. If your compiler is not strictly conformant, it will fail to construct a std::vector for such types.
More info:
http://en.cppreference.com/w/cpp/container/vector
http://en.cppreference.com/w/cpp/concept/CopyConstructible
http://en.cppreference.com/w/cpp/concept/CopyAssignable

undefined reference to vtable - virtual member, classes generated by gsoap

gsoap with its tools wsdl2h and soapcpp2 provided me with a soapStub.h file containing the following:
class SOAP_CMAC ns2__SOAPKunden
{
public:
std::string *adresszusatz;
// ...
public:
virtual int soap_type() const { return 7; }
// ...
ns2__SOAPKunden() : adresszusatz(NULL), x(NULL) { } // left out all member init.
virtual ~ns2__SOAPKunden() { }
};
I start with a small app using the class to populate objects with data from informix DB.
But to compile successfully i have to leave away all the virtual stuff - i found many postings about this error and use of virtual members in subclasses - otherwise i get
main.o: In function `ns2__SOAPKunden::ns2__SOAPKunden()':
main.cpp:(.text._ZN15ns2__SOAPKundenC1Ev[ns2__SOAPKunden::ns2__SOAPKunden()]+0xf): undefined reference to `vtable for ns2__SOAPKunden'
main.o: In function `ns2__SOAPKunden::~ns2__SOAPKunden()':
main.cpp:(.text._ZN15ns2__SOAPKundenD1Ev[ns2__SOAPKunden::~ns2__SOAPKunden()]+0x13): undefined reference to `vtable for ns2__SOAPKunden'
collect2: ld returned 1 exit status
I admit after years of scripting only it's very hard for me to make sense of C++ code... I want to ask for any advice what to try next. My class is no derived class, is for example what makes me wonder.
The error means that the virtual table has not been correctly compiled/linked in the final binary (executable or library). There are two common circumstances that lead to this error:
you are not linking the object file that includes the virtual table definitions --i.e. you compiled soapStub.cpp into soapStub.o, but did not add that binary to the linker command line.
the compiler is not generating the virtual table anywhere, so even if you are including all object files, that does not include the virtual table.
The second case is the hardest to identify for non-experienced developers, and can be caused by a class that is defined in the header and contains virtual functions. If all the virtual functions are defined inlined, the compiler will generate the virtual table in all translation units that include the header, and mark it as a weak symbol so that the linker can discard them, but if you later add a new virtual method and you leave it undefined in the header --or if you remove the definition from one of the virtual functions--, then the compiler will not generate the virtual table in each translation unit, but only in the one that defines those functions.
Things to check:
you are linking all object files
either all virtual functions are defined inline in the class definition or you have a .cpp that defines the virtual functions and you are linking that in.
This is what David Rodriguez said, just stated simpler I guess...
I had this situation in my interface class:
class IBase
{
public:
virtual void begin(unsigned long);
virtual void end();
virtual int available(void) = 0;
virtual int peek(void) = 0;
virtual int read(void) = 0;
virtual void flush(void) = 0;
}
and changed it to this:
class IBase
{
public:
virtual void begin(unsigned long) = 0;
virtual void end() = 0;
virtual int available(void) = 0;
virtual int peek(void) = 0;
virtual int read(void) = 0;
virtual void flush(void) = 0;
}
which did the trick.
begin() and end() were defined in derived class in a different file, IBase class (interface) was only declared in header and included in few places.
Error from OP only appeared when I set optimizations to none (-O0), any other setting resulted in no error (gcc 4.8).

GCC C++ Linker errors: Undefined reference to 'vtable for XXX', Undefined reference to 'ClassName::ClassName()'

I'm setting up a C++ project, on Ubuntu x64, using Eclipse-CDT. I'm basically doing a hello world and linking to a commerical 3rd party library.
I've included the header files, linked to their libraries, but I still get linker errors. Are there some possible problems here other than the obvious (e.g. I am 99% sure I'm linking to the correct library).
Is there a way to confirm the static libraries I am linking to are 64bit?
Is there a way to confirm that the library has the class (and methods) I am expecting it to have?
Eclipse says:
Building target: LinkProblem
Invoking: GCC C++ Linker
g++ -L/home/notroot/workspace/somelib-3/somelib/target/bin -o"LinkProblem" ./src/LinkProblem.o -lsomelib1 -lpthread -lsomelib2 -lsomelib3
./src/LinkProblem.o: In function `main':
/home/notroot/workspace/LinkProblem/Debug/../src/LinkProblem.cpp:17: undefined reference to `SomeClass::close()'
./src/LinkProblem.o: In function `SomeOtherClass':
/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:148: undefined reference to `SomeClass::SomeClass()'
/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:148: undefined reference to `vtable for SomeOtherClass'
/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:151: undefined reference to `SomeClass::~SomeClass()'
./src/LinkProblem.o: In function `~SomeOtherClass':
/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140: undefined reference to `vtable for SomeOtherClass'
/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140: undefined reference to `SomeClass::~SomeClass()'
/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140: undefined reference to `SomeClass::~SomeClass()'
collect2: ld returned 1 exit status
make: *** [LinkProblem] Error 1
This linker error usually (in my experience) means that you've overridden a virtual function in a child class with a declaration, but haven't given a definition for the method. For example:
class Base
{
virtual void f() = 0;
}
class Derived : public Base
{
void f();
}
But you haven't given the definition of f. When you use the class, you get the linker error. Much like a normal linker error, it's because the compiler knew what you were talking about, but the linker couldn't find the definition. It's just got a very difficult to understand message.
Assuming those methods are in one of the libs it looks like an ordering problem.
When linking libraries into an executable they are done in the order they are declared.
Also the linker will only take the methods/functions required to resolve currently outstanding dependencies. If a subsequent library then uses methods/functions that were not originally required by the objects you will have missing dependencies.
How it works:
Take all the object files and combine them into an executable
Resolve any dependencies among object files.
For-each library in order:
Check unresolved dependencies and see if the lib resolves them.
If so load required part into the executable.
Example:
Objects requires:
Open
Close
BatchRead
BatchWrite
Lib 1 provides:
Open
Close
read
write
Lib 2 provides
BatchRead (but uses lib1:read)
BatchWrite (but uses lib1:write)
If linked like this:
gcc -o plop plop.o -l1 -l2
Then the linker will fail to resolve the read and write symbols.
But if I link the application like this:
gcc -o plop plop.o -l2 -l1
Then it will link correctly. As l2 resolves the BatchRead and BatchWrite dependencies but also adds two new ones (read and write). When we link with l1 next all four dependencies are resolved.
Qt C++ will show this error when you change a class such that it now inherits from QObject (ie so that it can now use signals/slots). Running qmake -r will call moc and fix this problem.
If you are working with others via some sort of version control, you will want to make some change to your .pro file (ie add/remove a blank line). When everyone else gets your changes and runs make, make will see that the .pro file has changed and automatically run qmake. This will save your teammates from repeating your frustration.
The problem for me turned out to be pretty obscure. My class looked like this:
//-----------------------------------------
// libbase.h
class base {
public:
base() { }
virtual ~base() { }
virtual int foo() { return 0; }
};
//-----------------------------------------
//-----------------------------------------
// libbase.cpp
#include "libbase.h"
//-----------------------------------------
//-----------------------------------------
// main.h
class derived : public base {
public:
virtual int foo() ;
};
//-----------------------------------------
//-----------------------------------------
// main.cpp
int main () {
derived d;
}
//-----------------------------------------
The problem is in the linker. My header file went in a library somewhere, but all the virtual functions were declared 'inline' in the class declaration. Since there was no code using the virtual functions (yet), the compiler or linker neglected to put actual function bodies in place. It also failed to create the vtable.
In my main code where I derived from this class, the linker tried to connect my class to the base class and his vtable. But the vtable had been discarded.
The solution was to declare at least one of the virtual functions' bodies outside the class declaration, like this:
//-----------------------------------------
// libbase.h
class base {
public:
base() { }
virtual ~base() ; //-- No longer declared 'inline'
virtual int foo() { return 0; }
};
//-----------------------------------------
//-----------------------------------------
// libbase.cpp
#include "libbase.h"
base::~base()
{
}
//-----------------------------------------
In regards to problems with Qt4, I couldn't use the qmake moc option mentioned above. But that wasn't the problem anyway. I had the following code in the class definition:
class ScreenWidget : public QGLWidget
{
Q_OBJECT // must include this if you use Qt signals/slots
...
};
I had to remove the line "Q_OBJECT" because I had no signals or slots defined.
I had this error message. The problem was that I declared a virtual destructor in the header file, but the virtual functions' body was actually not implemented.
This error will also occur when we simply declare a virtual function without any definition in the base class.
For example:
class Base
{
virtual void method1(); // throws undefined reference error.
}
Change the above declaration to the below one, it will work fine.
class Base
{
virtual void method1()
{
}
}
In my case the problem occured when i forgot to add the =0 on one function in my pure virtual class. It was fixed when the =0 was added. The same as for Frank above.
class ISettings
{
public:
virtual ~ISettings() {};
virtual void OKFunction() =0;
virtual void ProblemFunction(); // missing =0
};
class Settings : ISettings
{
virtual ~Settings() {};
void OKFunction();
void ProblemFunction();
};
void Settings::OKFunction()
{
//stuff
}
void Settings::ProblemFunction()
{
//stuff
}
I stumbled across the issue now, too. The application defined a pure virtual interface class and a user-defined class provided through a shared lib was supposed to implement the interface. When linking the application, the linker complained that the shared lib would not provide vtable and type_info for the base class, nor could they be found anywhere else.
Turned out that I simply forgot to make one of the interface's methods pure virtual (i.e. omitted the " = 0" at the end of the declaration. Very rudimentary, still easy to overlook and puzzling if you can't connect the linker diagnostic to the root cause.
I had this error message when trying "hello world" like things with Qt. The problems went away by correctly running the qt moc (meta object compiler) and compiling+including these moc-generated files correctly.
If you have a base class with pure virtual function, make sure your base class constructor and destructor has body otherwise linker fails.
I put this for future visitors:
if you are receiving the error on creating an Exception object, then the cause of it probably is a lack of definition for what() virtual function.