49

別のデータ オブジェクトから取り込まれた新しい Foobar オブジェクトを返す静的ファクトリ メソッドを作成しました。私は最近、所有権のセマンティクスに夢中になっており、このファクトリ メソッドにunique_ptr.

class Foobar {
public:
    static unique_ptr<Foobar> factory(DataObject data);
}

私の意図は、ポインターを所有していることをクライアント コードに伝えることです。スマート ポインターがなければ、単純に を返しFoobar*ます。ただし、潜在的なバグを回避するためにこのメモリを強制的に削除したいのでunique_ptr、適切な解決策のように思えました. クライアントがポインターの有効期間を延長したい場合は.release()unique_ptr.

Foobar* myFoo = Foobar::factory(data).release();

私の質問は2つの部分に分かれています:

  1. このアプローチは正しい所有権のセマンティクスを伝えていますか?
  2. unique_ptrこれは、生のポインターの代わりに返す「悪い習慣」ですか?
4

3 に答える 3

60

ファクトリ メソッドから a を返すことstd::unique_ptrは問題なく、推奨される方法です。それが伝えるメッセージは (IMO):あなたは現在、このオブジェクトの唯一の所有者です。さらに、便宜上、オブジェクトは自分自身を破壊する方法を知っています。

これは、生のポインターを返すよりもはるかに優れていると思います (クライアントは、このポインターを破棄する方法と破棄するかどうかを覚えておく必要があります)。

ただし、ポインターを解放して寿命を延ばすことについてのあなたのコメントは理解できません。一般に、スマートポインターを呼び出す理由はめったにありませreleaseん。ポインターは常にある種の RAII 構造によって管理されるべきだと思うからです (私が呼び出す唯一の状況はrelease、ポインターを別の管理データ構造に置くことですunique_ptr。追加のクリーンアップを保証するために何かをした後、別の削除者) .

したがって、クライアントは、オブジェクト (または、ポインターの複数のコピーが必要な場合はa)が必要な限り、単にunique_ptrどこかに (返されたものから移動して構築された別の など) を格納できます (また、格納する必要があります)。したがって、クライアント側のコードは次のようになります。unique_ptrshared_ptr

std::unique_ptr<FooBar> myFoo = Foobar::factory(data);
//or:
std::shared_ptr<FooBar> myFoo = Foobar::factory(data);

個人的にはtypedef、返されたポインタ型 (この場合はstd::unique_ptr<Foobar>) や使用された削除機能 (この場合は std::default_deleter) をファクトリ オブジェクトに追加します。これにより、後でポインターの割り当てを変更することを決定した場合に簡単になります(したがって、ポインターの破棄には別のメソッドが必要です。これは、の 2 番目のテンプレートパラメーターとして表示されますstd::unique_ptr)。だから私はこのようなことをします:

class Foobar {
public:  
    typedef std::default_deleter<Foobar>     deleter;
    typedef std::unique_ptr<Foobar, deleter> unique_ptr;

    static unique_ptr factory(DataObject data);
}

Foobar::unique_ptr myFoo = Foobar::factory(data);
//or:
std::shared_ptr<Foobar> myFoo = Foobar::factory(data);
于 2012-01-03T22:00:26.830 に答える
17

std::unique_ptr指すオブジェクトを一意に所有します。「私はこのオブジェクトを所有していますが、他の誰も所有していません」と書かれています。

それはまさにあなたが表現しようとしていることです:あなたは「この関数の呼び出し元:あなたは今このオブジェクトの唯一の所有者です;あなたが好きなようにそれを使ってください、その寿命はあなたの責任です」と言っています。

于 2012-01-03T21:57:51.267 に答える
6

これは正しいセマンティクスを正確に伝え、C ++のすべてのファクトリが機能するはずだと私が考える方法ですstd::unique_ptr<T>。所有権のセマンティクスを強制せず、非常に安価です。

于 2012-01-03T21:58:47.833 に答える