Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Polymorphism exercise error message



  • Hi all

    I have an abstract base class Shape and three classes that derive from it Line Circle and rectangle. when I try to instantiate any class that derive from "Shape" I get an error message saying e.g undefined reference to vtable for Circle. I tried cleaning and rebuilding and running cmake again but still no change. Any idea why this is happening?

    my code:

    Shape.h
    @
    #ifndef SHAPE_H
    #define SHAPE_H
    #include <QString>

    class Shape
    {
    public:
    virtual QString getType();
    virtual double getArea() = 0;
    virtual QString toString() = 0;
    protected:
    QString type;
    };

    #endif // SHAPE_H
    @

    Circle.h
    @
    #ifndef CIRCLE_H
    #define CIRCLE_H
    #include <QString>
    #include "Shape.h"
    #include "Point.h"

    class Circle : public Shape
    {
    public:
    Circle(Point c, double r);
    double getArea();
    QString toString();
    private:
    Point center;
    double radius;
    };

    #endif // CIRCLE_H
    @

    Circle.cpp
    @
    #include "Circle.h"
    #include <math.h>
    #include <QString>

    Circle::Circle(Point c, double r) : center(c), radius(r) {
    }

    double Circle::getArea() {
    return M_PI * (radius * radius);
    }

    QString Circle::toString() {
    return QString("Center: %1 \n Radius: %2").arg(center.toString()).arg(radius);
    }
    @

    main.cpp
    @
    #include <QString>
    #include "Line.h"
    #include "Point.h"
    #include "Shape.h"
    #include "Circle.h"
    #include "Rectangle.h"
    #include "ShapeList.h"
    #include <QTextStream>

    QTextStream cout(stdout);

    int main() {
    ShapeList list;
    Point p1(0, 0);
    Point p2(-1, 0);
    Point p3(0, 1);
    Point p4(1, 1);

    Circle circle(p1, 1);
    Line line(p1, p2);
    Rectangle rectangle(p4, 3, 1);

    Shape* s1 = &circle;
    Shape* s2 = &line;
    Shape* s3 = &rectangle;

    list.append(s1);
    list.append(s2);
    list.append(s3);

    cout << "area of Circle with center (0,0) and radius 1 is " << s1->getArea() << endl;
    cout << "Area of any line is " << s2->getArea() << endl;
    cout << "Afea of rectangle with top lef corner (1, 1) and which also contains the point (3, 1) is " << s3->getArea() << endl;
    return 0;
    }
    @

    To make my post shorter I didn't include the Point Line Rectangle and ShapeList classes.


  • Lifetime Qt Champion

    Hi,

    Strange thing I can see: getType has no implementation.

    On a side note, none of your getter are constant
    and
    @
    Shape* s1 = &circle;
    Shape* s2 = &line;
    Shape* s3 = &rectangle;

    list.append(s1);
    list.append(s2);
    list.append(s3);
    @

    Is a bad Idea, you are taking the address of temporary variables. While this will work in this precise case, it's recipe for disaster later.



  • Thanks SGaist would it be better to add it to this list in this way: list.append(&circle)?
    I iplimented getType() and most of the errors disappeared.. The only one still there is undefined reference to vtable for Line... Any idea what that means?

    my code for Line:

    Line.h
    @
    #ifndef LINE_H
    #define LINE_H
    #include <QString>
    #include "Shape.h"
    #include "Point.h"

    class Line : public Shape {
    public:
    Line(Point p1, Point p2);
    double getArea();
    QString toString();
    private:
    Point oneEnd;
    Point otherEnd;
    };

    #endif // LINE_H
    @

    Line.cpp
    @#include "Line.h"

    Line::Line(Point p1, Point p2) : oneEnd(p1), otherEnd(p2) {
    type = QString("Line");
    }

    double getArea() {
    return 0;
    }

    QString Line::toString() {
    return QString("%1 %2").arg(oneEnd.toString()).arg(otherEnd.toString());
    }
    @

    my getType returns the type sent by it when any shape is initialized.


  • Lifetime Qt Champion

    No it would not since it's basically the same action but only on one line. You are still taking the address of a temporary. Either use a QList<Shape> or allocate your shapes on the heap. Since you have a pretty simple class you should rather go for QList<Shape>.

    Was Shape a QObject and you removed the Q_OBJECT macro ? If so, re-run qmake before building again.



  • No Shape wasn't a QObject strange that it only gives this error for Line and not Circle and Rectangle anymore...


  • Lifetime Qt Champion

    Compare all their implementations and see where you did something differently for Line


Log in to reply