C++ 接口来修改抽象属性
我想在元素中创建方法来修改元素的形状(即,如果形状是矩形,我必须能够更改长度和宽度,否则我必须能够向多边形形状添加点等) 例如,我不能声明一个setLength方法,因为setLength只是一个意义,如果_shape是一个矩形形状。一个解决方案是在矩形元素、多边形元素、循环元素中对元素进行子类化,但我希望避免这种解决方案。C++ 接口来修改抽象属性,c++,oop,C++,Oop,我想在元素中创建方法来修改元素的形状(即,如果形状是矩形,我必须能够更改长度和宽度,否则我必须能够向多边形形状添加点等) 例如,我不能声明一个setLength方法,因为setLength只是一个意义,如果_shape是一个矩形形状。一个解决方案是在矩形元素、多边形元素、循环元素中对元素进行子类化,但我希望避免这种解决方案。 您是否看到了另一种方法?可能是您可以执行以下操作: class AbstractShape; class RectangularShape : public Abstrac
您是否看到了另一种方法?可能是您可以执行以下操作:
class AbstractShape;
class RectangularShape : public AbstractShape
{
void setWidth(double v);
void setLength(double v);
};
class CircleShape : public AbstractShape
{
void setRadius(double v);
};
class PolygonalShape : public AbstractShape
{
void addPoint(Point p);
};
class Element
{
protected:
AbstractShape* _shape; //RectangularShape, PolygonalShape or CircleShape
};
在
\u形状上调用无意义函数将打印消息或断言。除了我提到的基本fat接口实现之外,如果您不想出于任何原因污染抽象基类,一种可能的解决方案是在另一个类上使用fat接口并
还请注意,您可能希望使用std::unique_ptr
,而不是原始指针访问者模式?矩形也应该是多边形,考虑添加一个间接层来变形。polygon@user1482030所以你想要一个胖接口?我认为你需要提供一个元素的假设用法,这样我们就可以看到你将如何使用它。然后我们可以回答你的问题(没有任何进一步的信息,我会说一个通常被认为是不好的做法的解决方案:在AbstractShape中添加一个虚拟函数,这样你就可以使用dynamic_cast来区分不同的类型)@StoryTeller请详细说明这是一个“好的”如果shape没有正确的动态类型,则设计添加可能毫无意义的方法?@user1482030大多数情况下,您没有太多选择。在这种情况下,你似乎没有太多选择。这就是为什么我建议在另一个类中添加那些无意义的函数,而不是基类,我想这会尽可能地保持基类的“正确”。例如,现在您可以添加一个getArea()
函数
class Shape
{
// ....
virtual void setWidth(double v) { /* not implemented, throw error ? */ }
virtual void setLength(double v){ /* not implemented, throw error ? */}
virtual void setRadius(double v){ /* not implemented, throw error ? */}
virtual void addPoint(Point p) { /* not implemented, throw error ? */}
//....
};
class RectangularShape : public Shape
{
void setWidth(double v) override ;
void setLength(double v) override;
};
class CircleShape : public Shape
{
void setRadius(double v) override ;
};
class PolygonalShape : public Shape
{
void addPoint(Point p) override;
};
class Element
{
protected:
Shape* _shape; //Any shape
};
class AbstractShape {};
class RectangularShape : public AbstractShape
{
public:
void setWidth(double v);
void setLength(double v);
};
class CircleShape : public AbstractShape
{
public:
void setRadius(double v);
};
class PolygonalShape : public AbstractShape
{
public:
void addPoint(Point p);
};
class Element {
public:
void setWidth(double);
void setLength(double);
void setRadius(double);
void addPoint(Point);
protected:
std::unique_ptr<AbstractShape> shape;
};
void Element::setWidth(double val) {
if (auto rectangle = dynamic_cast<Rectangle*>(this->shape.get())) {
rectangle->setWidth(val);
} else {
throw std::runtime_error{"This type does not implement setWidth()"};
}
}