【发布时间】:2022-01-20 16:25:57
【问题描述】:
我已经查看这段代码几个小时了,但我找不到为什么我不能实例化类。所以我有接口:
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));
}
};
我有两个类继承了这些接口:
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();
};
最后这两个类被一个代表形状的类继承:
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;
}
};
当我从 Shape2D 派生 Square 并创建克隆函数时,我收到错误,它是抽象类:
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
}
};
错误:不允许抽象类类型“Square”的对象
【问题讨论】:
-
virtual ~ICloneable() = 0 {}不是有效的 C++。您的代码也无法编译,因为它使用了未声明的类型,例如Point。 -
要使其有效,必须将其声明为
... = 0;,然后在类主体之外定义。 -
Clang gave me 作为非覆盖虚拟方法的列表。
virtual bool is_greater(const IPositionable& other)等不覆盖基类方法,因为参数类型不同。如果您使用override,编译器不会告诉您这一点。以后,请以minimal reproducible example 的形式附上代码——我们可以直接粘贴到编译器中而不会添加缺少的头文件或类的单件。 -
Shape2D继承了is_greater等的多个定义。人。来自IPositionable和I2DShape。您期望/希望它使用哪个? -
@Brian 我没有包括
Point,因为它是普通类。我修复了virtual ~ICloneable() = 0 {},但问题仍然存在。
标签: c++ inheritance abstract-class multiple-inheritance