So I'm just getting into polymorphism in C++. I have a class, Block, with public member virtual void Block::display(). In Dirt, a class that inherits from Block, I have member public void Dirt::display(). When I try to compile, I get the error in the title: [Linker Error] undefined reference to 'vtable for Block'. What does this error mean and, more importantly, how do I fix it?
I've never been able to exactly translate this message, but it normally relates to a virtual function being declared but not defined. Check all your virtual functions are either pure or defined.
Mostly.. Everything you have for the declarations is the same, except that in my Block.h file I declare display() as virtualvoid display(); without "Block::". Putting that bit of code in there, though, produces the same results.
I actually have a while loop in my main function in my main.cpp file that calls display... actually (I'm trying to make a clone of Minecraft) the display() in main() calls the display() in my Chunk class which cycles through a few for loops which call the display() functions on an array of Blocks which I have initialized as Dirt.
#include "Dirt.h"
Dirt::Dirt()
{}
void Dirt::display()
{
//OpenGL code for drawing a cube
}
The only other file I currently have is the default main.cpp that DevC++ creates for making an OpenGL project. I have not edited that at all. I am getting that error, the same as my project that has more than that code in it.
In both, the virtualvoid display(); is causing the problem because one of them isn't fully abstract. Either remove keyword virtual from one or add the full abstraction for one For example: virtualvoid display() = 0;, which would be in the base class you have in your design. I don't know if you need to display something in your Base block or not, but generally you wouldn't need to since it is a base object and usually would be inherited from and it needs full abstractions.
class Block
{
public:
Block();
virtualvoid display();
};
to
1 2 3 4 5 6
class Block
{
public:
Block();
virtualvoid display() = 0;
};
When the compiler compiles the Block code it is not creating a vtable for Block. Although you have a virtual function in there, so there should be a vtable, I think because there is no implementation of that method the compiler decides you don't want one.
By making the method pure virtual you are indicating to the compiler that there is no implementation for that method.
Which version of what compiler are you using? That kind of stuff has been part of c++ for 20+ years. DevC++ is an IDE not the compiler and I know it works with a few compilers.
The only other thing is gl/gl.h has something that is named block or dirt in it. Another thing you could try is adding namespace to your code. Doing that would isolate your code from the global namespace, which could be where the problem is occurring too because most the c code in gl/gl.h is in global namespace.
I'm using whatever the default compiler that comes with DevC++ 4.9.9.2 is. I read once that it was G++ 3.4 or something similar, although I don't really know.
There's no need for Block to display anything, all the displaying is done in the subclasses.
How do I add a namespace?
Removing the virtual keyword from Dirt.h produces the same result, both with and without Block::display being a pure virtual function.
One thing you could do is go get Code::Blocks with a new compiler with it. Current versions of g++ are 4.5/4.6. That might clean up the things you are fighting with but not entirely sure.
I downloaded and installed Code::Blocks and with it a whole host of new problems... The thing apparently can open DevC++ project files, but when I tried doing so it told me "No file extension manager found". I then decided to just create a new project and import all my source files into it, so I went to File>New>Project and it told me to select a template to create a project from, yet there were no templates. I decided then to just compile the source files outside of any project, but there doesn't seem to be a way to compile things... Help?