5

現在、生のポインターを使用する広範なコード ベースがあり、unique_ptr に移行したいと考えています。ただし、多くの関数はパラメーターとして生のポインターを想定しており、これらの場合に unique_ptr を使用することはできません。get() メソッドを使用して生のポインターを渡すことができることはわかっていますが、これにより、触れる必要があるコードの行数が増え、少し見苦しくなります。次のような独自の unique_ptr を作成しました。

template <class T>
class my_unique_ptr: public unique_ptr <T>
{
  public:

    operator T*() { return get(); };
};

次に、生のポインターを期待する関数 parm に my_unique_ptr を提供するたびに、自動的にそれを生のポインターに変換します。

質問: これを行うことについて本質的に危険なことはありますか? これは unique_ptr 実装の一部であると思っていたので、その省略は意図的なものだと思います-誰かが理由を知っていますか?

4

4 に答える 4

7

次のように、暗黙の変換で偶然に発生する可能性のある醜いことがたくさんあります。

std::unique_ptr<resource> grab_resource() 
{return std::unique_ptr<resource>(new resource());}

int main() {
    resource* ptr = grab_resource(); //compiles just fine, no problem
    ptr->thing(); //except the resource has been deallocated before this line
    return 0; //This program has undefined behavior.
}
于 2012-06-21T23:09:23.437 に答える
5

getで を呼び出すのと同じですが、unique_ptr<>自動的に実行されます。関数が戻った後にポインタが保存/使用されていないことを確認する必要があります(unique_ptr<>寿命が終了すると削除されます)。

deleteまた、生のポインターで (間接的であっても) 呼び出さないようにしてください。

さらにもう 1 つ確認すべきことは、ポインターの所有権を取得する別のスマート ポインター (たとえば、別のuniqe_ptr<>) を作成しないことです。上記の削除の注を参照してください。

unique_ptr<>自動的に変換を行わない (そして明示的に呼び出す必要がある)理由はget()、生のポインターにアクセスするタイミングを確実に制御できるようにするためです (そうしないとサイレントに発生する可能性がある上記の問題を回避するため)。

于 2012-06-21T20:44:24.990 に答える
2

に (生のポインターへの) 暗黙的な変換演算子を提供することの主な「危険」は、単一所有権のセマンティクスをモデル化することになってunique_ptrいるという事実に由来します。unique_ptrこれは、 をコピーすることはできないが、移動することはできる理由でもありunique_ptrます。

この「危険」の例を考えてみましょう:

class A {};

/* ... */

unique_ptr<A> a(new A);

A* a2 = a;
unique_ptr<A> a3(a2);

現在、指し示されているオブジェクトに対する2 つ unique_ptrのモデルの単一所有権のセマンティクスがあり、自由世界 (いや、宇宙) の運命はバランスにかかっています。

OK、私は少し劇的に言っていますが、それがアイデアです。

回避策に関する限り、私は通常.get()、ポインターを呼び出してそれを処理し、所有権の欠如を認識するように注意しgot()ます。

に移行しようとしている大規模なレガシーコードベースがあることunique_ptrを考えると、変換ラッパーは問題ないと思いますが、このコードを維持するときにあなたと同僚が将来間違いを犯さないことを前提としています. それが可能性が高いと思われる場合 (そして、私は偏執狂なので、通常そうします)、.get()暗黙的な変換を提供する代わりに、既存のすべてのコードを明示的に呼び出すように改造しようとします。コンパイラは、この変更を行う必要があるすべてのインスタンスを喜んで見つけます。

于 2012-06-22T13:06:41.990 に答える
1

unique_ptr にキャスト演算子を使用するのは危険ですか?

編集済みコメントを参照

---いいえ、確かに危険ではありません---:実際、標準では「安全なブール値」への暗黙的な変換が必要です( explicit安全なブール慣用句」を参照)。

編集の説明:

新しい標準 (unique_ptr も導入) では、explicit operator T()キャストが導入されました。unique_ptr に対しては、暗黙的な変換であるかのように引き続き機能します。つまりif ,whilefor(;x;)boolへの自動コンテキスト変換を行います。

私の弁護では、私の知識は主にBoostのような C++03 ライブラリに基づいており、これはimplicitへの変換を定義してます。unspecified-bool-type

これが他の人にとってまだ有益であることを願っています。


(生ポインタへの変換を含む、より標準的な扱いについては、他の回答を参照してください)

于 2012-06-21T23:19:47.557 に答える