移動のセマンティクスを実装していない(つまり、移動コンストラクタと移動代入演算子)、プログラムの正確さだけでなく、その性能に影響を与える例があると、私は迷っていました。正確性に影響を与える移動コンストラクタ/代入演算子の例?
答えて
これは、次のコピー・セマンティクスを実装する1つ(またはそれ以上)である任意の値型のようになります。
不合理(通称:クラスの設計と正反対)
インポッシブル
は
"非合理的"カテゴリは、unique_ptr
のようなタイプになります。タイプの論理設計によって無意味なコピーが行われます。
「不可能」カテゴリには、システム外に存在する多くのAPIのラッパータイプが含まれます。
一部のOpenGLオブジェクトにはラッパータイプがあるとします。 OpenGLはクエリー可能なAPIであるため、古いオブジェクトから状態を取得して新しいオブジェクトに設定することで、オブジェクトのコピーを合理的に実装することができます。
しかし、これはOpenGL拡張のために欠陥があります。オブジェクトに新しい状態を与えることができます。これらの拡張機能の前に書かれたコードは何も知らないでしょう。
最後のカテゴリは奇妙に聞こえます。しかし、そのOpenGLラッパーの考え方を考えてみましょう。コピーを実装するとします。そして、あなたはバッファオブジェクト(GPUメモリのセクション)をコピーしています。
まあ...どこでコピーしていますか?あなたは、OpenGLコンテキストの現在のスレッドでそれをやっていますか?そのオブジェクトは他のスレッドで同時に更新されていますか?競合状態を作成したようなことですか?
競合状態を回避するためにmutexを使用することもできますが、デッドロックの可能性が非常に高くなりました。どうして?多くのオブジェクトにはバッファオブジェクトが含まれているためです。これらのオブジェクトをコピーすると、必然的にそれらのバッファをコピーする必要があります。したがって、複数のミューテックスをロックして仕事をするマルチコピー操作があります。同じバッファをコピーしている場合、他のマルチコピー操作に対してデッドロックする可能性があります。
デッドロックが発生したり、メモリのコピーが矛盾したり、まったくコピーできなくなったりします。
あなたのタイプがコピーを許可しない場合、タイプのデザインがそうでないと言わない限り、あなたは動くことが許されるべきです。
(私はあなたがあまりにもこのクラスをコピーする方法はありません示唆していると仮定するつもりです。)
まあ、例がstd::unique_ptr
です。このポインタは、new
で動的に割り当てられたオブジェクトの唯一の所有権を持つことになっているため、2人の所有者を持つことができないためコピーコンストラクタを許可する意味がありません。ただし、移動代入演算子と移動コンストラクタは、割り当てられたオブジェクトを移動できるように実装されています。移動中であるため、unique_ptr
から移動したオブジェクトはオブジェクトに対して所有権を持たなくなりましたが、移動したunique_ptr
はこのオブジェクトを所有しています。これは唯一の所有権の部分に違反していません。これらの移動セマンティクスがなければ、unique_ptr
ははるかに少ないユースケースしか持たないでしょう。
より一般的には、移動代入演算子/移動コンストラクタなしでオブジェクトを移動しようとしない限り、「はプログラムの正確さに影響します。非常に具体的なクラスは、これらのクラスがそうすることができないので、このNotCopyable/NotMovable拘束(例えばstd::mutex
)を持っています。関数からオブジェクトを返すだけのpre-C++では、すでにCopyableかMovableのどちらかである必要があることに注意してください。これらのクラスのユースケースは限られています。
- 1. オペランドのオーバーロード演算子+オペランドに影響を与えずに
- 2. 移動代入演算子C++
- 3. 代入演算子を持つコンストラクタ
- 4. ビット操作演算子の優先順位が出力に与える影響
- 5. 非invokablesの代入演算子の例?
- 6. 代入演算子のオーバーロードのアプリケーション例
- 7. 移動代入演算子を呼び出すことによって移動コンストラクタを実装する
- 8. 代入演算子
- 9. Javaコンパウンド代入演算子と代入演算子
- 10. C#参照代入演算子?例えば
- 11. typedefフレンドのコンストラクタ/代入演算子を作成する関数
- 12. Entity Framework移行履歴の場所に影響を与える自動移行
- 13. JavaScriptの代入演算子
- 14. テンプレートクラスの代入演算子
- 15. デフォルトの代入演算子
- 16. JavaScriptの代入演算子
- 17. 代入演算子を計算する
- 18. 動的バインディングを持つクラスの代入演算子を移動する
- 19. 多くのテーブルに影響を与えるDB移行のベストプラクティス
- 20. コピーコンストラクタと代入演算子
- 21. Ruby代入演算子
- 22. Autohotkey:=と=代入演算子
- 23. ハンドルクラスと代入演算子
- 24. 代入演算子(Java)
- 25. コンストラクタとコピー代入演算子をコピーしますか?
- 26. 代入演算子の代わりに配置演算子とコピーコンストラクタを使用
- 27. 位置の計算に影響を与えるCSSスケール変換
- 28. ボタンに影響を与える移動した機能に触れる
- 29. スコアペナルティを使用して次の移動に影響を与える
- 30. スタイルから子コントロールのプロパティに影響を与える方法
この仮説タイプではコピーのセマンティクスが正しく実装されていると仮定していますか? –
@NicolBolas例を見つけるのに役立つ任意の仮定 – bennyl
私はなぜdownvoteがわからないのですか?私は合法的な質問だと思う、http://en.cppreference.com/w/cpp/language/rule_of_threeは、 "3のルールとは違って、ムーブ・コンストラクターとムーブ・アサインメントの提供に失敗したのは通常エラーではなく、失敗した最適化の機会。私は "普通"の部分について迷っていた – bennyl