2016-08-23 17 views
1

Shapeへのポインタを格納するDomainとします。正確な形状(TriangleまたはRectangle)はコンパイル時には分かりませんし、入力を読み込んだ後は明らかになります。実行時に、派生構造の変数にアクセスする必要があるかもしれませんが、ポインタが基本構造を指しているため、これは不可能です。私は "スイッチオンタイプ"を行うもう一つの解決策を見つけましたが、回答hereで指摘されているように落胆しています。彼はまた、あなたがポリモーフィズムを使用する場合多型の良い実践

が、あなたは、基本クラスの参照/ポインタの後ろに何があるかを気にする必要はありませんと言いました。

この場合、私は多形を使用すべきではないと思われるので注意します。私は下のことは悪いデザインだと思いますが、この問題を解決するには良いデザインは何ですか?

struct Shape 
{ 
    int common_variable; 
}; 

struct Triangle: Shape 
{ 
    int triangle_specific_variable; 
}; 

struct Rectangle: Shape 
{ 
    int rectangle_specific_variable; 
}; 

struct Domain 
{ 
    Shape* shape; 
}; 

int main() 
{ 
    Domain domain; 
    //domain.shape = new Triangle(); // depends on input. 
    //domain.shape = new Rectangle(); // depends on input. 

    return 0; 
} 
+0

私は非常にあなたの質問や、あなたの例を理解していない。これを行うには

一つの方法は、「ビジターパターン」です。ここでは多態的なアプローチが役に立つと思われますが、私はあなたが手助けできるようにしようとしていることを十分に理解していません。 – callyalater

+0

@callyalater:派生構造体固有の変数にアクセスする必要がありますが、ポインタが基本構造を指しているため、アクセスできません。 – Shibli

+0

'Base'ポインタを介して' Derived'構造体のメンバにアクセスしたい場合は、 'dynamic_cast'を使うことができますが、' Base'クラスの多態性クラスを作る必要があります。例えば 'virtual void f(){ } '関数です。 – PcAF

答えて

6

あなたの質問は明確にあなたがなど、三角形、rechtangles、と仕事をしたいとあなたはすべてのこれらの形状であることを知っているように、多型のために必要を示しています。

スイッチを使用して特定のデータにアクセスすることをお勧めしないのはなぜですか?

これはまさに多形性の設計とは反対であるためです。図形を使って作業したり、描いたり、領域を計算したりするのではなく、常に図形の種類とコード固有の動作を知る必要があります。

コードを完成した後、正方形と円が必要であることがわかったとします。これを維持するのは悪夢です。

これを解決するにはどうすればよいですか?

具体的なクラスから抽象化し、一般的なシェイプで実行できる一般的な操作を定義する必要があります。次に、これらの操作を仮想関数として定義し、ドメイン内のコードで仮想関数を呼び出します。

さらに拡大するには、クラスからオブジェクトを作成する代わりに、たとえばストリームからシェイプを返すファクトリメソッドを使用できます。

例:スマートポインタでの作業は生のポインタを持つよりも安全だろうと

class Shape 
{ 
public: 
    virtual void scale(double scale_factor)=0; 
    virtual void rotate(double angle)=0; 
    virtual void draw(window w)=0; 
    virtual Shape* clone()=0; 
    virtual ~Shape() {} 
}; 

class Triangle: public Shape 
{ 
    Point A, B, C; 
public: 
    Triangle (Point a,Point b, Point c) : A(a), B(b), C(c) { } 
    void scale(double scale_factor) override; 
    void rotate(double angle) override; 
    void draw(window w) override; 
    Shape* clone() { return new Triangle(*this); }  
}; 

... 

int main() 
{ 
    Domain domain, domain2; 
    Window wnd = CreateWindow(...); // depends on your GUI library 
    Point a,b,c; 
    cin >> a >> b >> c; 
    domain.shape = new Triangle(a,b,c); 

    // Once the object is constructed no need to know the details of the shape here 
    domain.shape->rotate(45); 
    domain2.shape = domain.shape->clone(); 
    domain.shape->draw(wnd); 
    ... 
    return 0; 
} 

注意。

0

最初。ポリモーフィズムは、具体的なオブジェクトがまったく同じインターフェースを持つ場合、ほとんどの場合、ジョブの正しいツールに過ぎません。

第2に、これはまれであり、多型は変異よりも適している場合があります。

このような状況では、オブジェクトの外側から推測しようとするのではなく、実装にその動作を延期します。

struct triangly_thing { int i; }; 
struct rectangly_thing { int i; }; 

struct shape_visitor 
{ 
    virtual void operator()(triangly_thing thing) const 
    { 
     // do triangly things 
    } 

    virtual void operator()(rectangly_thing thing) const 
    { 
     // do rectangly things 
    } 
}; 

struct Shape 
{ 
    int common_variable; 

    virtual void visit(shape_visitor const& visitor) 
    { 

    } 
}; 


struct Triangle: Shape 
{ 
    triangly_thing my_triangly_thing; 

    void visit(shape_visitor const& visitor) override 
    { 
     visitor(my_triangly_thing); 
    } 
}; 

struct Rectangle: Shape 
{ 
    rectangly_thing my_rectangly_thing; 

    void visit(shape_visitor const& visitor) override 
    { 
     visitor(my_rectangly_thing); 
    } 
}; 

struct Domain 
{ 
    Shape* shape; 
}; 

int main() 
{ 
    Domain domain; 

    struct my_shape_visitor_type : shape_visitor 
    { 
     // customise overrides in here 
    } my_shape_visitor; 

    domain.shape->visit(my_shape_visitor); 

    return 0; 
} 
関連する問題