Search code examples
c++linker-errorsvtableundefined-reference

Linker Error: Undefined Reference to `vtable for square`. Code includes virtual functions


I've checked the most common undefined reference to vtable question on here, and while that gave me a better understanding of what is going on, I still wasn't able to gather enough information to figure out why I'm having this error.

I have a simple Square class, which, originally I was trying to inherit from a Polygon class. Since I've been relatively knew to C++ and still learning, I haven't experimented with Polymorphism all that much.

Anyway, after I tried getting rid of the base class (Polygon), I thought that might help things. Unfortunately, I'm still getting the same error, and I don't quite know what is going on. What I do know is that originally, the Polygon class required a source file with at least a constructor definition, which I did give. That got rid of the vtable error for the Polygon class.

My main issue is that I'm still getting this for the Square class, which was supposed to inherit from the Polygon class. What I'd like to know is how can I implement this properly to avoid getting a vtable error while still getting the benefits of Polymorphism?

Code

Polygon.h/.cpp

#ifndef POLYGON_H
#define POLYGON_H

#include "Shape.h"
#include "vector3f.h"

class Polygon
{
public:
    Polygon();
    virtual void Collide(Shape &s) = 0;
    virtual void Collide(Polygon &p) = 0;
    virtual bool Intersects(const Shape &s) = 0;
    virtual bool Intersects(const Polygon &s) = 0;
protected:
    virtual void Draw() const = 0;
};

#endif // POLYGON_H

//------------------

#include "Polygon.h"

Polygon::Polygon() {


}

*Square.h/.cpp

#ifndef SQUARE_H
#define SQUARE_H

#include "Polygon.h"
#include "Shape.h"
#include "Vec3f.h"
#include <QGLWidget>

class Square //: public Polygon
{
public:
    Square(Vec2f lenwidth = Vec2f(), Vec3f color = Vec3f());
    ~Square();

    virtual void Collide(Shape &s);
    virtual void Collide(Square &s);
    virtual void Collide(Polygon &p);
    virtual bool Intersects(const Shape &s);
    virtual bool Intersects(const Polygon &p);
    virtual bool Intersects(const Square &s);
    virtual float Area(void) const;

protected:
    virtual void Draw();

private:
    Vec2f mDimensions;
    Vec3f mColor;

};

#endif // SQUARE_H

//----------------

#include "Square.h"

/**********/
/* PUBLIC */
/**********/

Square::Square(Vec2f lenwidth, Vec3f color) //: Polygon()
{
    this->mDimensions = lenwidth;
    this->mColor = color;
}

Square::~Square() {

}

void Square::Collide(Polygon &p) {

}

/************/
/* PRIVATE  */
/************/

void Square::Draw() {
    const int numPoints = mDimensions.X * mDimensions.Y;
    glBegin(GL_LINE_STRIP);
    glColor3f(mColor.X, mColor.Y, mColor.Z);

    for (double i = 0; i <= numPoints; i++) {
        const float x = mDimensions.X;
        const float y = mDimensions.Y;

        glVertex3f(x, y, 0.0);

        mDimensions.X += 1;
        mDimensions.Y += 1;
    }
}

Solution

  • The reason for the vtable linking error is that you are not defining the first virtual function in your class(which is Collide(Shape&p)). (vtables are usually stored along with the first virtual function definition)

    Add a void Square::Collide(Shape &p) function( just a blank void Square::Collide(Shape &p) {} should work) and that specific vtable error should go away.

    Note that you are probably should define all the functions in your header.

    Remember, arguments types differentiate functions just like names in C++, a Collide(Shape) is different from a Collide(Polygon).