用于修改抽象属性的接口

时间:2017-06-21 08:15:05

标签: c++ oop

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
};

我想在Element中创建方法来修改Element的形状_shape(即如果形状是Rectangular,我必须能够改变长度和宽度,否则我必须能够为多边形添加一个Point形状等)。

例如,我不能声明一个setLength方法,因为如果_shape是一个RectangularShape,setLength只是一个含义。解决方案是在RectangularElement,PolygonalElement,CircularElement中继承Element,但我想避免这种解决方案。 你看到另一种方法吗?

2 个答案:

答案 0 :(得分:0)

可能你可以做以下事情:

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
};

_shape上调用无意义的函数将打印消息或断言。

答案 1 :(得分:0)

除了我提到的基本胖接口实现之外,如果您不想因任何原因污染您的抽象基类,一种可能的解决方案是在另一个类上使用fat接口并capability queries

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; 
};

例如setWidth()的实现可能看起来像这样

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()"};
    }
}

另请注意,您可能希望使用std::unique_ptr而不是原始指针。