2012-04-03 8 views
3

私はこのようなものがあります:C++:参照や工場

struct D { 
    virtual void operator() {...}; 
} 
struct D1 : public D { 
    virtual void operator() {...}; 
} 
struct D2 : public D { 
    virtual void operator() {...}; 
} 

void foo(D &d) {...}; 

をだから、これは結構です、とうまく私のD'sののライフサイクルを制御します

foo(D()); 
foo(D1()); 
foo(D2()); 

しかし、私は私のDバリアントを選択してください複数の場所で、私は単純な工場が欲しい:

const D& make_D() 
{ 
    // BAD, returning reference to temporary 
    if(is_tuesday()) 
     return D1(); 
    return D2(); 
} 

一時的な参照を返す代わりに、私はオブジェクトを返すことができますct、しかし私は基本クラスにスライスします。あるいは、工場からポインタを返すこともできますが、クライアントはそれを削除する必要があります。他のより複雑なソリューションでも、クライアントに負荷がかかります。

D& d = make_D(); 
foo(d); 

(あるいはfoo(make_D()))のようなものを書くための方法はありますか?目的はさまざまなDの定義とmake_D()の複雑さを包み込んで、foo()のような関数とそれらの関数を呼び出す関数がそれを心配する必要がないようにすることです。

+0

注意:非const値のリファレンスにテンポラリをバインドすることはできないため、 'foo(D())'はコンパイルされません(適合するコンパイラの下ではなく、 。 –

答えて

5

通常の方法は、ポインタまたはスマートポインタを返すことです。

ポインタを使用することの欠点は、ユーザーがそのメモリを管理できるようにすることです。

スマートポインタを返す場合、これはもはや問題ではありません。

const SmartPtr<D> make_D() 
{ 
    if(is_tuesday()) 
     return SmartPtr(new D1()); 
    return SmartPtr(new D2()); 
} 
5

残念ながら、これは不可能です。

通常、私がやっていることは(std::unique_ptrを使用することはできませんとき、時々std::shared_ptrstd::unique_ptrを使用することです:

typedef std::unique_ptr<D> Dptr; 
Dptr make_D() 
{ 
    Dptr p(nulptr); 

    if(is_tuesday()) 
     p.reset(new D1); 
    else 
     p.reset(new D2); 

    return p; 
} 
0

まず、私は理解してあまりよく分かりません。表示されたコードは ではなく、コンパイルされません。

struct D 
{ 
    virtual void operator()() const { /* ... */ } 
}; 

と::

void foo(D const& d) { /* ... */ } 

呼び出し、または可変であるあなたはそれがないことを確認していますか?おそらく 引数を渡さないので、使用した後でオブジェクトを捨てることになるので、おそらくはそうではありません。 は、静的インスタンスへの参照を単純に返します。これは私が使用する通常の ソリューションです。そうでなければ、コピー可能オブジェクト は文字封筒イディオムを使用して多態的に動作することができますが、通常 は各コピーの実際のオブジェクトのクローンを必要とするため、作業のビットは です。

関連する問題