I believe this can also happen when you have a base class with a function defined like
Code:
virtual some_func()=0;
and you have a derived class that should provide a body for the definition of the function but the function body is missing. This can happen if the function definition really is missing, or maybe the compiler just didn't build the object file where it is (which is why a clean & build sometimes fixes the problem).
The vtbl is a hidden part of the class that holds pointers to a class's virtual methods. It's an array of pointers, and the array has to be placed in one and only one object file; it has to go somewhere but you can't have duplicates of it. But where to put it? C++ doesn't enforce that a class be placed in any particular file (it's not like Java which requires each class to have a file). So the compiler sticks the vtbl in at whichever file is first place where a virtual method is defined. Sometimes the compiler gets confused and thinks it has already put the vtbl in somewhere else when it hasn't (which is when the problem is with the compiler). Other times it is because you declared a virtual method but forgot to define any virtual methods for the class, in which case the problem is with you and you need to provide a definition for the virtual method.
The reason it gives a strange linker error when you make this mistake, rather than the compiler helpfully telling you "hey dummy you forgot to define this method" is because each time the compiler compiles 1 cpp file at a time, it has no way of knowing that you aren't going to go ahead and define the virtual method somewhere later. Eventually all the compiling is done and the virtual method wasn't found, but by that time
it's too late for the compiler to do anything about it. It's a limitation of C++'s compilation model. By this time it is the linker that is running, the linker discovers the error but linkers were invented for assembly language and C, they don't "speak" C++, so they don't give a C++ error, they give a linker error talking about a
detail of the C++ implementation that you normally don't see when things are working right.