Fixing “undefined reference to `vtable for …”

These annoying errors have been haunting me the last couple of days, so I figured I should share the most common reason for their occurrence. That is in my projects at least.

This error is caused because the linker in gcc is unable to find the functions you have defined in your headers in your actual code. So if you have a header which looks like this:

#ifndef MESH_H
#define MESH_H

class Mesh
{
public:
    Mesh();
    ~Mesh();
    virtual void draw();
};

#endif // MESH_H

You must at least have these functions defined in your .cpp file:

#include "mesh.h"

Mesh::Mesh() {
}

Mesh::~Mesh() {
}

void Mesh::draw() {
}

After this, make sure you clean your compile environment to make sure no object files are being misinterpreted by the compiler. If you are using Qt or a project with a Makefile, you could just run these three commands (the first only applies to Qt projects).

qmake
make clean
make

Should you still have trouble, make sure that qmake is actually generating your .moc files for any objects that need them. Sometimes it might even be necessary to empty the build directory completely yourself to make sure there are no files left behind that are not cleaned by make clean.

Published by

Svenn-Arne Dragly

I'm a physicist and programmer, writing about the stuff I figure out as I go.

16 thoughts on “Fixing “undefined reference to `vtable for …””

  1. Hi Svenn,

    Nice of you for sharing your knowlage!
    But your tips didn’t help in my case.
    I get the error message “undefined reference to `vtable for …”
    although the .h and .cpp files are synchronized and checked.
    I’ve also cleaned the environment.
    Have you any other tips?

    1. Hi Teymoor,

      vtable errors are sometimes tricky to figure out. I would double check the following:
      1. All methods in your classes are both defined in the headers (.h) and the source files (.cpp)
      2. All methods have matching parameters
      3. The number of methods are the same
      4. If you have inherited classes, make sure that all virtual functions are implemented (this shouldn’t lead to vtable errors, but is worth checking)
      5. Check that all used libraries are included and check that you are also linking their dependencies.
      6. Try to compile your project with only a few test files, but link and use the libraries you need. A vtable error could mean that a library that is referenced is missing some of its dependencies or that these dependencies are not linked properly.
      7. Start from the bottom and build up everything again piece by piece, if possible. This way you can try find the problem in your code.

      If you can’t figure it out, see if you can create a simple example that reproduces the error and post it here. Maybe I or someone else that stumbles over this post knows what to do.

      Good luck!

    2. This may cause your problem:


      class Mesh
      {
      public:
      Mesh();
      ~Mesh();
      virtual void draw();
      };

      class Object : Mesh
      {
      public:
      Object();
      ~Object();
      void draw();
      };

      (...)


      void draw() {
      }

      Differs from


      void Object::draw() {
      }

      This may sound silly, but I often forget to put the "classname::" identifier. When you have virtual methods undeclared in an inherited class, the compiler will yield "undefined reference to `vtable for classname`", instead of "undefined reference to `classname::methodname`"

    3. My problem went away when I made my method “pure virtual”.

      In my case, I changed:

      struct FUN
      {
      virtual double operator()(double x, double y) const ;
      };

      to
      struct FUN
      {
      virtual double operator()(double x, double y) const = 0;
      };

  2. I still am getting errors even if I combine all .h and .cpp code into main.cpp.

    obj\Debug\main.o||In function `fourSided':|
    C:\Users\Eric\Desktop\Code\Programs\instincts physics\main.cpp|40|undefined reference to `vtable for fourSided'|
    C:\Users\Eric\Desktop\Code\Programs\instincts physics\main.cpp|40|undefined reference to `vtable for fourSided'|
    C:\Users\Eric\Desktop\Code\Programs\instincts physics\main.cpp|51|undefined reference to `vtable for fourSided'|
    C:\Users\Eric\Desktop\Code\Programs\instincts physics\main.cpp|51|undefined reference to `vtable for fourSided'|
    ||=== Build finished: 4 errors, 22 warnings ===|
    
    
    
    #include "instinct.h"
    
    using namespace std;
    
    class fourSided
    {
        private:
            int x;
            int y;
            Point point;
            int width;
            int height;
            Color color;
            Rect rect;
        public:
            fourSided();
            fourSided( int&, int&, int&, int&, Color& );
            virtual bool checkEdge( fourSided& ) const;
    
            virtual void setX( int& x )
                { this -> x = x; }
            virtual void setY( int& y )
                { this -> y = y; }
            virtual void setWidth( int& width )
                { this -> width = width; }
            virtual void setHeight( int& height )
                { this -> height = height; }
            virtual void setColor( Color& color )
                { this -> color = color; }
    
            virtual int getX() const { return this -> x; }
            virtual int getY() const { return this -> y; }
            virtual int getWidth() const { return this -> width; }
            virtual int getHeight() const { return this -> height; }
            virtual Color getColor() const { return this -> color; }
    
            virtual ~fourSided();
    };
    
    fourSided::fourSided() //  x = 0;
        this -> y = 0;
        this -> width = 0;
        this -> height = 0;
        this -> color = BLACK;
        this ->  point = Point( x, y );
        this -> rect = Rect( point, width, height, color );
    }
    
    fourSided::fourSided( int& X, int& Y, int& WIDTH, int& HEIGHT, Color& COLOR )  //error ^ line 51
    //    :x( X ), y( Y ), width( WIDTH ), height( HEIGHT ), color( COLOR )
    {
        this -> x = X,
        this -> y = Y,
        this -> width = WIDTH;
        this -> height = HEIGHT;
        this -> color = COLOR;
        this -> point = Point ( this -> x, this -> y );
        this -> rect = Rect( point, this -> width, this -> height, this -> color );
    }
    
    int instinct_main()
    {
    
        return 0;
    }
    
    1. the constructor definition actually looks like different. Made an error while pasting.

      fourSided::fourSided()
      {
      this -> y = 0;
      this -> width = 0;
      this -> height = 0;
      this -> color = BLACK;
      this -> point = Point( x, y );
      this -> rect = Rect( point, width, height, color );
      }
      
      1. Hi Eric!

        The reason is because you have made some functions virtual without giving them any body. You either have to

        a) Create an empty body that will be called if no child class reimplements the function
        b) Create a child class that implements the virtual functions and compile + link this together with your fourSided class.

        It is possible to compile the class without defining the virtual functions, but as soon as the linker tries to look up the function definitions it finds nothing and fails with the vtable error.

        So a working version of your class looks like this:

        class fourSided
        {
        private:
            int x;
            int y;
            Point point;
            int width;
            int height;
            Color color;
            Rect rect;
        public:
            fourSided();
            fourSided( int&, int&, int&, int&, Color& );
            virtual bool checkEdge( fourSided& ) const {return false;}
        
            virtual void setX( int& x )
            { this -> x = x; }
            virtual void setY( int& y )
            { this -> y = y; }
            virtual void setWidth( int& width )
            { this -> width = width; }
            virtual void setHeight( int& height )
            { this -> height = height; }
            virtual void setColor( Color& color )
            { this -> color = color; }
        
            virtual int getX() const { return this -> x; }
            virtual int getY() const { return this -> y; }
            virtual int getWidth() const { return this -> width; }
            virtual int getHeight() const { return this -> height; }
            virtual Color getColor() const { return this -> color; }
        
            virtual ~fourSided() {}
        };
        
  3. Problem temporarily solved. It works if I define the constructors within the scope of the public.

        public:
            fourSided()
                {
                    this -> x = 0;
                    this -> y = 0;
                    this -> width = 0;
                    this -> height = 0;
                    this -> color = BLACK;
                    this ->  point = Point( x, y );
                    this -> rect = Rect( point, width, height, color );
                }
            fourSided( int& X, int& Y, int& WIDTH, int& HEIGHT, Color& COLOR )
                {
                    this -> x = X,
                    this -> y = Y,
                    this -> width = WIDTH;
                    this -> height = HEIGHT;
                    this -> color = COLOR;
                    this -> point = Point ( this -> x, this -> y );
                    this -> rect = Rect( point, this -> width, this -> height,
                                        this -> color );
                }
    
  4. I hit a nasty version of this error.
    I have a QT4 class:

    class TestBench : public QMainWindow
    {
    Q_OBJECT
    public:
    TestBench(QWidget *parent = 0);
    ~TestBench();
    Ui::testBenchForm ui;

    public slots:
    void Start();
    void Abort();
    ….

    and the corresponding cpp file defines ALL the methods in the class template.
    I get a “undefined reference to vtable for TestBench” on all these methods, in the .o file that obviously has been linked in. None of these methods is virtual, but defining one as virtual, to force the creation of a vtable, does not work.

    objdump reports that the TestBench vtable is among the unresolved externals in TestBench.o

Leave a Reply