2017-06-21 14 views
0
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のシェイプを作成する必要があります(シェイプがRectangularの場合、長さと幅を変更できる必要があります。多角形などにポイントを追加することができるなど)。抽象的な属性を変更するインタフェース

たとえば、setLengthは_shapeがRectangularShapeの場合にのみ意味があるため、setLengthメソッドを宣言することはできません。解決策は、RectangularElement、PolygonalElement、CircularElementのElementをサブクラス化することですが、この解決法を避けたいと思います。 これを行う別の方法がありますか?

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

ビジターパターン? – StoryTeller

+1

矩形もポリゴンでなければなりません。多角形をモーフする間接レイヤーを追加することを検討してください。 – Curious

+0

@ user1482030太いインターフェイスが必要なのですか? – Curious

答えて

0

では、次のような何かを行うことができますように。

0
私が言及した基本的な脂肪インタフェースの実装以外に

、あなたは一つの可能​​な解決策は、別のクラスに脂肪インターフェイスを使用することで、何らかの理由であなたの抽象基底クラスを汚染したくない場合や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()"}; 
    } 
} 

このようになります。また、あなたはおそらく01を使用することに注意してくださいであり、生のポインタではありません。

+0

形状に正しい動的タイプがない場合、意味を持たないメソッドを追加するのは「良い」デザインですか? – user1482030

+0

@ user1482030あなたはほとんどの選択肢がありません。この場合、多くの選択肢はないようです。だから私は、これらの意味のない関数を基本クラスではなく、別のクラスに追加することを提案しました。これは可能な限り基底クラスを「正しい」状態に保ちます。これで 'getArea()'関数を追加することができます – Curious

関連する問題