2017-01-06 33 views
0

クラスを持っていますが、1つのメソッドのオーバーロードされたバージョンはほとんどありません。すべてのバージョンは1つのパラメータ(オブジェクト)をとります。そのオブジェクトは常に1つの基本クラスから派生しています。 (Baseクラスのパラメータを取るメソッドはありません)。派生クラスへの基本クラスのキャスト

class Base { ... } 
class Object1 : public Base { ... } 
class Object2 : public Base { ... } 
class Object3 : public Base { ... } 

class T 
{ 
    // ... 
    do_sth(const Object1& obj); 
    do_sth(const Object2& obj); 
    do_sth(const Object3& obj); 
    // ... 
} 

そしてIは(のみ)派生クラスオブジェクトを含む、Baseクラスを指すunique_ptrでベクトルを作成します。

std::vector<std::unique_ptr<Base>> vect; // then some push_backs 

は今、私はこのように、vect内のすべてのオブジェクトに対してT::do_sthを呼びたい:render(*object)通話do_sth(Base)が、それも存在しないため、

for (auto& object : vect) 
    T_obj.do_sth(*object); 

しかし、その方法は、それは、IMPOSIBLEだ(およびその行動を望んでいないだろう)。私はその行をいくつかの異なる(キャストを使用して)置き換えようとしましたが、私の試みは成功しませんでした。それを修正するには?

+0

[派生クラスのC++のキャスト]の可能な重複(http://stackoverflow.com/questions/5313322/c-cast-to-derived-class) –

+2

'do_sth'のための関数のシグネチャとは何であり、 'レンダリング'?オブジェクトを値渡ししていますか?あなたは[最小、完全で、証明可能な例](http://stackoverflow.com/help/mcve)を提供できますか? – qxz

+0

@Quentin @qxz:私は私の例で間違いがあった、私はそれを編集しました。 'do_sth'パラメータは常にconst参照です。 私は 'do_sth(dynamic_cast (* object));'を試しましたが、ナイスセンスです... – mdjdrn1

答えて

4

コメントから「ノーあらゆるObjectクラス、ない仮想関数を修正する」の要件を考えると、ここにあなたの最初のソリューションは、dynamic_castのようです、thusly使用:

for (auto const& uObj : vect) { 
    if(auto *obj = dynamic_cast<Object1 const *>(uObj.get())) 
     T_obj.do_sth(*obj); 
    else if(auto *obj = dynamic_cast<Object2 const *>(uObj.get())) 
     T_obj.do_sth(*obj); 
    else if(/* ... */) 
     // And so on. 
} 

私は使い捨てを使用したいところ通常だことマクロ - 自己責任で使用してください。

#define DYNAMIC_CALL_DO_STH(Type) \ 
    if(auto *obj = dynamic_cast<Type const *>(uObj.get())) \ 
     T_obj.do_sth(*obj) 

for (auto const& uObj : vect) { 
    DYNAMIC_CALL_DO_STH(Object1); 
    else 
    DYNAMIC_CALL_DO_STH(Object2); 
    else 
    DYNAMIC_CALL_DO_STH(Object3); 
} 

#undef DYNAMIC_CALL_DO_STH 
+0

それが仮想メソッドなしで私の問題を解決する唯一の方法ならば、私のプロジェクトの現在の構造のためだけです。新しい派生クラスを追加すると、そのループに変更が加わります。 'do_sth'が仮想関数なら、私はrange-based forループで呼び出すことができます.-はるかに単純です。あなたの答えをありがとう。 – mdjdrn1

+0

@mdjdrn1よく、あなたは仮想関数の長所と欠点をすべて指摘してきました;)1つの場所で派生クラスの単一のリストを維持することに悩むことができれば、確かにマクロ+ 、あまりにも。 – Quentin