[Linker Error] undefined reference to 'vtable for Block'?

Pages: 12
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?
should work.

does Block::display() have an implementation or is it pure virtual (void Block::display() = 0) ?
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.
so just to be clear, OP:

you have a header file like this
1
2
3
4
5
6
class Block 
{
   public:
   virtual void Block::display( );
   //otherstuff
}


and you have another header file liek this
1
2
3
4
5
6
class Dirt : public Block
{
   public:
   void display( );
   //otherstuff
}


and finally your implementation like this
1
2
3
4
void Dirt::display( )
{
   while(1){fork( );}
}


is that pretty much accurate?
Mostly.. Everything you have for the declarations is the same, except that in my Block.h file I declare display() as virtual void 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.
bump
Can you repro the problem with a minimal and complete, stripped down version of the code which can be posted here?
Repro? Mean you repost?
Can you repro-duce the same problem with a short bit of code.

To help isolate the problem.
Well, here's the relevant code:

Block.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
 #ifndef BLOCK_H
#define BLOCK_H

#include <windows.h>
#include <gl/gl.h>

class Block
{
      public:
           Block();
           virtual void display();
};
#endif 


Block.cpp:
1
2
3
#include "Block.h"

Block::Block() {}


Dirt.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef DIRT_H
#define DIRT_H

#include <windows.h>
#include <gl/gl.h>

#include "Block.h"

class Dirt : Block
{
      public:
           Dirt();
           virtual void display();
};
#endif 


Dirt.cpp:
1
2
3
4
5
6
7
8
9
#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.
I've only just had a quick look at your post, and have to go (and catch a train)

But I notice you're using private inheritence. Try...

1
2
3
4
5
6
class Dirt : public Block // was the missing public a typo?
{
      public:
           Dirt();
           virtual void display();
};
That was not a typo, my code didn't have the public keyword in there. If I put it in there, however, I get the same results.
1
2
3
4
5
6
7
8
9
10
11
12
13
14

 #ifndef BLOCK_H
#define BLOCK_H

#include <windows.h>
#include <gl/gl.h>

class Block
{
      public:
           Block();
           virtual void display();
};
#endif  


and
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef DIRT_H
#define DIRT_H

#include <windows.h>
#include <gl/gl.h>

#include "Block.h"

class Dirt : Block
{
      public:
           Dirt();
           virtual void display();
};
#endif  


In both, the virtual void 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: virtual void 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.

I don't know if that will help you.
I think you need to change

1
2
3
4
5
6
class Block
{
      public:
           Block();
           virtual void display();
};


to

1
2
3
4
5
6
class Block
{
      public:
           Block();
           virtual void 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.

Sorry, doing that produces the same results. Is there a problem with DevC++ and inheritance?
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.

This is information on Name spaces:
http://www.learncpp.com/cpp-tutorial/711-namespaces/

Code::blocks can be found:
http://www.codeblocks.org/

Code::Blocks ships with G++ 4.5, I believe, if you get the version with mingw.

You might have to get glut for mingw though.
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?
Hmmm... you aren't alone with this prob. Someone managed to fix it back in 2008, but didn't say what there fix was. :-(

"undefined reference to vtable"
http://www.codeguru.com/forum/showthread.php?t=466688

Does DevC++ allow you to turn on verbose logging of the link phase, to make sure it's linking block.obj/.o, etc properly.

Andy
Pages: 12