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
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.