2017-07-11 8 views
0

質問をスマートポインタを使用して:私はのベクトル(共有を持っているように、派生クラス、Widgetを構築するにはどうすればよい:(序文を新たにし、C++のオブジェクト指向プログラミング)冒頭で、派生クラスのコンストラクタに

?)ポインタは、元のオブジェクト(それが派生クラスのままであるような)は、ポインタのキャストと参照解除の際にアクセスできます。



は、私は、基本クラスを持っていると言う:

class Component { 
public: 
    int a; 
    int b; 
    virtual void rtti(){}; // for run time type information. 
    explicit Component(int a, int b) { this->a = a; this->b = b;} 
} 

そして、2つの派生クラス、さらに

class AComponent:public Component{ 
public: 
    using Component::Component; 
    AComponent(int a, int b) : Component(int a, int b){} 
}  

class BComponent:public Component{ 
public: 
    using Component::Component; 
    BComponent(int a, int b) : Component(int a, int b){} 
} 

、Iは、多成分(ここではまだ一般的な)を持っています:

typedef shared_ptr<AComponent> AComponentPtr; 
typedef shared_ptr<BComponent> BComponentPtr; 
class MultiComponent{ 
public: 
    vector<AComponentPtr> A_components; 
    vector<BComponentPtr> B_components; 

    explicit MultiComponent(vector<AComponentPtr> As, vector<BComponentPtr> Bs){ 
     this->A_components = As; 
     this->B_components = Bs; 
    } 
} 

最後に、私はこのコンポーネント階層の特定のユースケースがあります。現在

class WidgetComponentA:public AComponent{...} 
class WidgetComponentB:public BComponent{...} 

class Widget:public MultiComponent{ 
public: 
    using MultiComponent::MultiComponent; 

    Widget(WidgetComponentA a, WidgetComponentB b, WidgetComponentB c) 
     : MultiComponent(???){ 
    } 
} 

を、私は次のように設定WidgetMultiComponentクラスのコンストラクタを持っている:

class Widget:public MultiComponent{ 
public: 
    using MultiComponent::MultiComponent; 

    Widget(WidgetComponentA a, WidgetComponentB b, WidgetComponentB c) 
     : MultiComponent({(AComponentPtr)&a},{(BComponentPtr)&b, (BComponentPtr)&c}){} 
} 

この利回りので、コンパイル時にエラーは発生しません。

その後、私はそうのように私の主な方法でウィジェットを構築:Widget widgetオブジェクト内

main(){ 

    WidgetComponentA a = WidgetComponentA(1,2); 
    WidgetComponentB b = WidgetComponentB(3,4); 
    WidgetComponentB c = WidgetComponentB(5,6); 

    // now, the widget: 

    Widget widget = Widget(a,b,c); 

    // however, the pointers within the widget 
    // do not access valid addresses in memory. 

return 0;} 

共有ポインタは、メモリ内の任意の有効な場所を参照し、で失敗していない、

メモリにない値のアドレスを取得しようとします。



最終的に、私は何をしようとしていることだけで、基本クラスの共有ポインタの形で様々な派生型のコンポーネントのリストを保持Widget持っています。

次に、クラスに対して汎用のテンプレート関数を実行し、ウィジェット固有の派生クラスポインタへのポインタをウィジェット固有の関数にキャストします。

私はメモリリークの警告に走ったので、私は、安全のために、共有のポインタを使用しています...しかし、簡単な解決策があるかどうか...

+1

'AComponentPtr)&a' < - Cスタイルのキャストを使用して、すぐにスコープから' shared_ptr'インスタンスに移動する変数へのポインタをキャストします。一般に、コードはすべてのレベルで壊れています。たとえば、抽象クラスには、一時オブジェクトの作成とスライスを可能にするコピーコンストラクタがあります。 – VTT

+0

なぜ多型を使用しないのですか? – Charles

+0

@VTTので、コンストラクタに入る前に共有ポインタベクトルを作成する必要がありますか? – bordeo

答えて

2

私はコメントで示唆したように、おそらくpolymorphic approachが容易になるだろう...

class MultiComponent{ 
    public: 
    typedef std::vector<std::shared_ptr<Component>> components_vec; 
    components_vec components; 

    MultiComponent(components_vec& cv){ 
     components = cv; 
    } 
} 

class Widget: public MultiComponent { 
    public: 

    Widget(MultiComponent::components_vec& cv) 
     : MultiComponent(cv){} 
} 

あなたはComponentComponent*へ年代の子孫へのポインタをキャストして、それらを一緒に保存することができます。

次に、virtual void Component::display() = 0を定義して、継承者が必要に応じて何らかの動作を定義するようにします。

+0

'MultiComponent(components_vec&cv){...}'の中で '&'が何をしているのか尋ねることができますか? – bordeo

+1

@chrisdパラメータ 'cv'を参照として使用します。 – Charles

1

はおそらく、私はあなたが求めるものを誤解していますが対処したい場合共有所有権のオブジェクトは、あなたがそれらをそのようにする必要がありで:

main() 
{ 
    auto a = std::make_shared<WidgetComponentA>(1,2); 
    auto b = std::make_shared<WidgetComponentB>(3,4); 
    auto c = std::make_shared<WidgetComponentB>(5,6); 

    // now, pass the shared stuff to widget: 

    Widget widget = Widget(a,b,c); // make sure that Widget has 
            // such constructor that accepts 
            // the shared pointers 

    return 0; 
} 
関連する問題