-1

I'm making a little program for school. I want to add virtual destructor to the class 'IObject', 'Square' and 'RotatedSquare'. But when I do, it gives an error. Is it not possible in this case or how to do it here? here's my code:

interface iobject :

#ifndef IOBJECT_H_
#define IOBJECT_H_
#include "Point.h"

class IObject {
public:
    virtual const Point& getPosition()const = 0;
    virtual double getSize()const = 0;
    //virtual ~IObject();

};

#endif

class square

#ifndef SQUARE_H_
#define SQUARE_H_
#include "IObject.h"
#include "Point.h"
#include <iostream>
class Square : public IObject{
private:
    Point position;
    double size;
public:
    Square(const Point& position, const double size):position(position),size(size){};
    virtual const Point& getPosition() const {return this->position;}
    virtual double getSize() const {return this->size;}
    friend std::ostream& operator<<(std::ostream& out, const Square& s);
    //virtual ~Square();

protected:
    virtual void print(std::ostream& out) const;
};

#endif 

class RotatedSquare

#ifndef ROTATEDSQUARE_H_
#define ROTATEDSQUARE_H_
#include "Square.h"

class RotatedSquare : public Square{
private:
    double angle;
public:
    RotatedSquare(const Point& position, const double size, const double angle): Square(position,size),angle(angle){};
    double getAngle() const {return this->angle;}
    //virtual ~RotatedSquare();
protected:
    virtual void print(std::ostream& out) const;
};

#endif

the error :

Undefined symbols for architecture x86_64:
  "Square::~Square()", referenced from:
      _main in Practice.o
  "vtable for RotatedSquare", referenced from:
      RotatedSquare::RotatedSquare(Point const&, double, double) in Practice.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "vtable for Square", referenced from:
      Square::Square(Point const&, double) in Practice.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "vtable for IObject", referenced from:
      IObject::IObject() in Practice.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.

the main class :

#include <iostream>
#include "Point.h"
#include "IObject.h"
#include "Square.h"
#include "RotatedSquare.h"

int main() {

     IObject* s1 = new Square(Point(1,4),2.2);
     std::cout << s1->getPosition() << std::endl;
     std::cout << s1->getSize() << std::endl;
  Square s2 = Square(Point(4,5),5);
  Square* s3 = new RotatedSquare(Point(5,5),8,60);
  std::cout << s2 << std::endl;
  std::cout << *s3;
return 0;
}
sg_sg94
  • 2,248
  • 4
  • 28
  • 56

3 Answers3

2

You need to define each of the virtual destructors you declare. Assuming you don't want the destructor to do more than the default behavior, you can make the definition with the declaration: Instead of:

virtual ~IObject();

use

virtual ~IObject() {}

If you want to do significant work in the destructor, or generally prefer all definitions in cpp rather than hpp, then define the destructor in a cpp file (keep the declaration without definition in the hpp)

IObject::~IObject()
{
// Whatever needs to be done
}
JSF
  • 5,281
  • 1
  • 13
  • 20
  • Thank you ! You know why I can't delete doubles in destructors? c++ says this :cannot delete expression of type 'double' – sg_sg94 Aug 05 '15 at 11:08
  • 1
    delete is for objects owned through pointers. The expression type given to delete must be a pointer. If you allocated a double with `new` it would be correct to `delete` it, and you would do so with an expression for a pointer to that double, not an expression for the double itself. If the double is part of some other object, or a local variable, or otherwise not directly allocated with `new` then it is not correct to `delete` it. – JSF Aug 05 '15 at 11:26
0

You need to define the virtual destructors in your code. As clearly mentioned in your error.

"Square::~Square()", referenced from:
      _main in Practice.o
  "vtable for RotatedSquare", referenced from:
      RotatedSquare::RotatedSquare(Point const&, double, double) in Practice.o

NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.

Writing virtual ~IObject() {} will suffice.

Nishant
  • 1,635
  • 1
  • 11
  • 24
0

Your destructors are missing definitions.

You can simply use the compiler-generated one if you don't want to provide your own:

virtual ~X() = default;

This is better than providing an empty body:

virtual ~X() { }

because a user-provided1 destructor prevents the class from being trivially destructible.


1 { /* anything */ } makes it user-provided, = default does not.

Emil Laine
  • 41,598
  • 9
  • 101
  • 157