2

リファクタリングしているコードには、次の形式の関数があります。

A f()
{
    if(existing)
        return A();
    else
        return A(handle);
}

Safe Bool Idiom は、後で A がハンドルに関連付けられているかどうかをテストするために使用されます。つまり、実行のために内部的に有効なハンドルを必要とするこのオブジェクトのクラス メソッドを呼び出す必要があるかどうかをテストします。A のメソッドは const です。

代わりに、ここでインターフェイス IA を返したいと思います。したがって、ポインターを返す必要がありますか? もしそうなら、ブースト共有ポインタを使用します。ポインターが何かを指しているかどうかをテストできます。

代わりにここで参照を操作する方法はありますか? そのようなアプローチをお勧めしますか、それともboost::shared_ptrsが進むべき道だと思いますか?

アップデート

A は IA から派生します。

私のコンパイラは gcc バージョン 4.4.3 です。

このコードの最大の問題は、外部の C API と対話するために A が使用されていることです。したがって、A のモックとその実装である A のベースとして IA インターフェイスを使用して、モックを作成したいと思います。次に、ファクトリとして表示される上記のメソッド f() の外では、IA ポインターのみを使用します。つまり、依存性注入です。

したがって、A は基本的にハンドルであり、ハンドルを必要とする一連の C API 関数へのインターフェイスです。インターフェイスは同じでハンドルが異なるタイプ A のオブジェクトをいくつか持つことができます。

4

5 に答える 5

4

私はstd::unique_ptr< AI >オブジェクトを返します:

std::unique_ptr< AI > f()
{
    if(existing)
        return std::unique_ptr< AI >( new A() );
    else
        return std::unique_ptr< AI >( new A(handle) );
}

上記の場合、スライスは行われず、コンパイラーは*オブジェクトを移動します。

* c++11 を使用していると仮定しました。


あなたはc++ 11を使用していないので、最も簡単なのは次を使用することboost::shared_ptrsです:

boost::shared_ptrs< AI > f()
{
    if(existing)
        return boost::shared_ptrs< AI >( new A() );
    else
        return boost::shared_ptrs< AI >( new A(handle) );
}

このような場合、作成されたオブジェクトが破棄されるかどうか、いつ破棄されるかを気にする必要はありません。はそれboost::shared_ptrsを処理します。

于 2012-07-03T08:50:00.020 に答える
2

ポインターも使用しますが、参照を使用することもできます。

A& f()
{
    if(existing)
    {
        static A a;
        return a;
    }
    else
    {
        static A a(handle);
        return a;
    }
}

あなたはその意味を十分に認識していますよね?つまり、参照を再割り当てすることはできず、それを変更することはローカルstatic変数を変更することを意味します。

于 2012-07-03T08:39:01.473 に答える
1

コード スニペットからA、 function でオブジェクトを構築しているようですf。そのような場合、オブジェクトを値で返すことがおそらく最善の方法です。コンパイラは戻り値の最適化 ( RVO ) を使用し、すべてのコピーを最適化します。

値によるオブジェクトの受け渡しについては、Dave Abrahams によるこの記事を参照してください。

の基本クラスを返す場合、スライスの問題Aにより、この解決策は機能しないことに注意してください。オブジェクトを返すことが問題ない場合は、これがおそらく最良の解決策です。A

于 2012-07-03T08:40:49.993 に答える
1

ポインターを理解できる場合は、ポインターを操作します。それができない場合は、今あるものにとどまります。あなたがポインターを避けるために最善を尽くした前の男のように見えます。betabandido が言ったように、紙の上では遅いように見えても、コンパイラはそれを最大限に活用します。

インターフェイスは、ポインターを最大限に活用するための設計パターンです。ポインターとキャストがなければ、あまり意味がありません。

ポインターが何かを指しているかどうかをテストするために、NULL 値があります。ハエを撃っている場合は、大砲を展開する必要はありません。

現在のコードに満足できない理由を説明してください。たぶん、問題はそれほど深刻ではありません。

于 2012-07-03T09:11:08.350 に答える
0

ポインタを返すことは 1 つの方法です。

私にとって、もう 1 つの単純でネイティブな方法は、メソッドのシグネチャに戻り値を追加することです。

int f(A & a)
{
    if(existing)
    {
        return ERROR_ALREADY_EXISTS;
    }
    else
    {
        A temp(handle);
        a = temp;
        return SUCCEEDED;
    }
}
于 2012-07-03T08:56:09.397 に答える