既存のコードを「近代化」しようとしています。
これはうまく機能しますが、コードを「近代化」するには、変数を"std::unique_ptr<Device> device_"
として定義するように変更し、deleteの明示的な呼び出しを削除する必要があると考えました。
私の質問はこれです-
.getを呼び出して、各関数呼び出しで生のポインターを取得できます。しかし、それは見苦しく、そもそもunique_ptrを使用する理由のいくつかを無駄にします。
または、「every」関数を変更して、「Device *」タイプのパラメーターを受け取る代わりに、「std :: unique_ptr&」タイプのパラメーターを受け取るようにすることもできます。これは(私にとって)関数プロトタイプを多少難読化し、読みにくくします。
これのベストプラクティスは何ですか?他のオプションを見逃していませんか?
Modern C++スタイルでは、2つの重要な概念があります。
所有権は、オブジェクト/リソース(この場合、Device
のインスタンス)の所有者に関するものです。さまざまな std::unique_ptr
、boost::scoped_ptr
またはstd::shared_ptr
は所有権に関するものです。
Nullityははるかに単純ですが、特定のオブジェクトがnullであるかどうかを表すだけであり、他のことは一切気にせず、所有権については確かに気にしません!
あなたはrightクラスの実装をunique_ptr
(一般的に)。ただし、目標がPIMPLの実装である場合は、ディープコピーセマンティクスを備えたスマートポインターが必要になる場合があります。
これは、クラスがこのメモリの唯一の原因であることを明確に示しており、それ以外の場合にメモリがリークする可能性のあるすべての方法をきちんと処理します。
一方、ほとんどのリソースのsersは、所有権についてあまり気にすることができませんでした。
関数がオブジェクトへの参照を保持しない限り(マップなどに保存します)、重要なのは、オブジェクトの有効期間が関数呼び出しの期間を超えることです。
したがって、パラメーターの受け渡し方法の選択は、可能性のあるNullityに依存します。
それは本当に依存しています。関数がunique_ptrの所有権を取得する必要がある場合、その署名は_unique_ptr<Device>
_ bv valueを取得し、呼び出し元は_std::move
_ポインターを取得する必要があります。所有権が問題にならない場合は、生のポインターシグネチャを保持し、get()
を使用してポインターunique_ptrを渡します。これは見苦しくありませんif問題の関数は所有権を引き継ぎません。
私は使うだろう std::unique_ptr const&
。非const参照を使用すると、呼び出された関数にポインターをリセットする可能性が与えられます。
これは、呼び出された関数がポインターを使用できるが、それ以外は使用できないことを表現する良い方法だと思います。
だから私にとっては、これによりインターフェースが読みやすくなります。私は、渡されたポインターをいじる必要がないことを知っています。
ベストプラクティスは、おそらくこの場合std::unique_ptr
を使用しないことですが、それは依存します。 (通常、クラス内の動的に割り当てられたオブジェクトへの生のポインタを複数持つべきではありません。これも依存します。)この場合にしたくないことの1つは、std::unique_ptr
(およびお気づきのとおり、std::unique_ptr<> const&
は少し扱いにくく、難解です)。これがオブジェクト内で動的に割り当てられた唯一のポインタである場合、生のポインタとデストラクタ内のdelete
のみを使用します。そのようなポインターが複数ある場合は、それらをそれぞれ個別の基本クラスに委任することを検討します(未加工のポインターでもかまいません)。
それは実行不可能かもしれませんが、_Device*
_のすべての出現を_const unique_ptr<Device>&
_で置き換えることは良い出発点です。
明らかに_unique_ptr
_ sをコピーすることはできず、移動したくないでしょう。 _unique_ptr
_への参照に置き換えると、既存の関数の本体の本体が機能し続けることができます。
トラップがあります。呼び出し先がunique_ptr.reset()
またはunique_ptr().release()
を実行しないようにするには、_const &
_を渡す必要があります。これはまだ変更可能なポインターをデバイスに渡すことに注意してください。このソリューションでは、_const Device
_へのポインターまたは参照を渡す簡単な方法はありません。