I've been looking at this code for few hours and I can't find why I can't instantiate class. So I have interfaces:
class ICloneable {
public:
virtual ICloneable* clone() const = 0;
virtual ~ICloneable() = 0 {}
};
class IPrintable
{
protected:
virtual void print(std::ostream&) const = 0;
public:
virtual ~IPrintable() = 0;
friend std::ostream& operator<<(std::ostream, const IPrintable&);
};
std::ostream& operator<<(std::ostream os, const IPrintable& other) {
other.print(os);
return os;
}
class IComparable {
protected:
virtual bool is_greater(const IComparable& other) const = 0;
virtual bool is_equal(const IComparable& other) const = 0;
public:
virtual ~IComparable() = 0;
virtual bool operator>(const IComparable& other) const {
return is_greater(other);
}
virtual bool operator<(const IComparable& other) const {
return !(is_greater(other) || is_equal(other));
}
virtual bool operator==(const IComparable& other) const {
return is_equal(other);
}
virtual bool operator!=(const IComparable& other) const {
return !(is_equal(other));
}
};
And I have two classes that inherit these interfaces:
class I2DShape : public IComparable, public IPrintable {
public:
virtual void print(std::ostream& os) const override final {
os << "Circumference: " << this->circumference();
}
virtual bool is_greater(const I2DShape& other) const final {
return this->circumference() > other.circumference();
}
virtual bool is_equal(const I2DShape& other) const final {
return this->circumference() == other.circumference();
}
virtual double circumference() const = 0;
virtual ~I2DShape();
};
class IPositionable : public IPrintable, public IComparable {
public:
virtual void print(std::ostream& os) const override final {
}
virtual bool is_greater(const IPositionable& other) const final {
distance_from_origin() > other.distance_from_origin();
}
virtual bool is_equal(const IPositionable& other) const final {
distance_from_origin() == other.distance_from_origin();
}
virtual double distance_from_origin() const {
return sqrt(pow(center().get_x(), 2) pow(center().get_y(), 2));
}
virtual Point center() const = 0;
virtual ~IPositionable();
};
And in the final these two classes are inherited by one which represents shape:
class Shape2D : public IPositionable, public I2DShape, public ICloneable {
protected:
int num_of_points;
Point* points;
public:
Shape2D() : num_of_points(0), points(nullptr) {}
Shape2D(int num) : num_of_points(num), points(new Point[num]) {}
Shape2D(const Shape2D& other) : num_of_points(other.num_of_points) {
points = new Point[num_of_points];
for (int i = 0; i < num_of_points; i ) {
points[i] = other.points[i];
}
}
Shape2D& operator=(const I2DShape& other) {
}
virtual Shape2D* clone() const override = 0;
virtual ~Shape2D() {
if(points)
delete[] points;
}
};
When I derive Square from Shape2D and make function for cloning, I get error that it's abstract class:
class Square : public Shape2D {
private:
double side;
public:
Square() {}
Square(double s, Point center) : side(s), Shape2D(1) { points[0] = center;}
virtual Point center() const override{
return points[0];
}
virtual double circumference() const override {
return 4 * side;
}
virtual Square* clone() const override final {
return new Square(*this); //error on this line
}
};
Error: object of abstract class type "Square" is not allowed
CodePudding user response:
Since in interfaces you declared destructors with = 0
you are forcing explicit implementation of it in sub-classes which can be instantiated.
There are two ways to fix it.
- Make interface classes in standard way with default destructors (no
= 0
), using{}
or= default
. - Add explicit destructor for
Square
Note that pure virtual destructor with implementation is treated by gcc and clang as an error.
Related SO questions:
CodePudding user response:
The error was as @HolyBlackCat stated in the comments, with function is_greater
and is_equal
because they have different parameters when overriden. Simple fix to this was to remove = 0
from those two functions in IComparable
so they weren't pure.