開いうC++0xの移動意味論?
-
25-09-2019 - |
質問
問題の種類"外部資源のように std::vector<T>
または std::string
)でコピーし傾向にある非常に高価である、コピーして作成した暗黙のうちに様々なコンテキストながっていただきます。C++0xの対応は、この問題は 移動意味論, るconceptionallyという考え方に基づいた資源pilferingと技術力 rvalue参照.
開いても同じようなものは動意味論やrvalue参考文献?
解決
私は、DはC ++がそれらのコピーになるだろう、一方、それらを移動するために管理している(ように構造体を返すなど)D内のいくつかの場所があると信じています。 IIRC、コンパイラは、構造体のコピーが少ないDでC ++よりも起こっていてコピーは、必要とされていないことを確認することができ、いずれの場合に移動ではなくコピーを行います。クラスが参照されているので、もちろん、彼らは全く問題ありません。
しかしかかわらず、すでにC ++よりもDで異なる働き建設をコピーします。 this(this)
:一般的には、代わりにコピーコンストラクタを宣言するのは、postblitコンストラクタを宣言します。 this(this)
が呼び出される前に、それは完全なのmemcpyを行い、そしてあなただけの完全に新しいの作成とは反対に、新しい構造体は、(そのような必要なメンバ変数のディープコピーを行うなど)、オリジナルとは別であることを保証するために必要なものは何でも変更しますすべてをコピーする必要がありますコンストラクタ。だから、一般的なアプローチは、すでにC ++とは少し異なっています。コピー構造体は安価でなければなりません - - それはC ++にあるであろうよりも、それは問題の少ないですので、また、一般的に構造体が高価postblitコンストラクタを持つべきではないということに合意しています。コピーに高価であるオブジェクトは、一般的に参照またはCOWセマンティクスを持つクラスや構造体のいずれかです。
コンテナは、一般的に参照型ですそれはC ++になりますように高価ではありません。
非常によく、それは移動コンストラクタに似たものを使用することができますDのケースがあるかもしれませんが、一般的には、Dは、それがどこにもいないので、C ++は、周りのオブジェクトをコピーして持っていることの問題を軽減するように設計されていますそれはC ++であることを問題に近います。
他のヒント
Dて別の値とオブジェクトのセマンティクス
- の場合を宣言する型オブジェクトとして
struct
, ここにお集まりの価値の意味はデフォルト - の場合を宣言する型オブジェクトとして
class
, ここにお集まりのオブジェクトの意味.
今とおな管理メモリを自分でデフォルトの場合はD-使用ガベージコレクタ-しているオブジェクトの種類として宣言された class
自動的にポインタ(または"参照"希望の場合は、実際のオブジェクトのオブジェクトそのものです。
なので、ベクトルの周辺の開発を研究し、そのままパスのリファレンス/ポインタです。ます。ないコピー(以外のコピーを参照)。
そのたD、C#、Java、その他の言語なの"必要性"移動の意味として最も種類のオブジェクトの意味と操作を参照ではなく、コピー.
ば実施し、本当のところはわからないけど。が問われていることは、そうした環境を取り入れ性能を向上させてC++?自然がいなかったのでしょうかがあると思われます。
私はなんとかう気持ち、実際にrvalue参考文献全体の概念の移動"を意味"の結果で通常のC++で作成地域"仮設"スタックオブジェクト。 Dは、最もGCの言語でも共通してオブジェクトのヒープ、そしてありません架を一時オブジェクトのコピー(移動)を数回に戻る際のテーマによって呼び出しスタック -することなくメカニズムによる架です。
D(最GC語) class
オブジェクトがコピーされません暗黙のうちに、だけですからの参照を、この 月 いきれるかというとそうではあなrvalue参照します。
大藤玲, struct
物体があるように想定していない"を扱うための資源"が、簡単な値型の行動に似た組み込みタイプなので、再度な理由で動意味論、まぁ.
このことは、結論-Dなrvalue refでは必要ありませんし.
しかし、まだ使用rvalueを参考に練習っただけに、読み込みしないスキップも実際の利用の場合のおすすめします。扱ってくださいこれでは最後に、これまで様々なバンチの想いはどういうものだとしてではなく、信頼性判断を下しています。
私はすべての答えは完全に元の質問に答えることができなかったと考えています。
前述のようにまず、質問は構造体のためにのみ関係します。クラスは、意味のある動きを持っていません。また前述した、構造体のために、動きの一定量が一定の条件の下で、コンパイラによって自動的に行われます。
あなたは、移動操作の制御を取得したい場合は、ここにあなたがしなければならないものです。あなたは@disableで(これ)これに注釈を付けることにより、コピーを無効にすることができます。次に、あなたはconstructor(constructor &&that)
を定義することにより、C ++のthis(Struct that)
を上書きすることができます。同様に、あなたはopAssign(Struct that)
との割り当てを無効にすることができます。どちらの場合も、あなたはあなたがthat
の値を破壊することを確認する必要があります。
this
の古い値を破壊する必要があるため、割り当てについては、最も簡単な方法は、それらを交換することです。 C ++のunique_ptr
の実装だろう、このようなので、見て何かます:
struct UniquePtr(T) {
private T* ptr = null;
@disable this(this); // This disables both copy construction and opAssign
// The obvious constructor, destructor and accessor
this(T* ptr) {
if(ptr !is null)
this.ptr = ptr;
}
~this() {
freeMemory(ptr);
}
inout(T)* get() inout {
return ptr;
}
// Move operations
this(UniquePtr!T that) {
this.ptr = that.ptr;
that.ptr = null;
}
ref UniquePtr!T opAssign(UniquePtr!T that) { // Notice no "ref" on "that"
swap(this.ptr, that.ptr); // We change it anyways, because it's a temporary
return this;
}
}
編集:
お知らせ私はopAssign(ref UniquePtr!T that)
を定義していませんでした。これは、コピー代入演算子あり、そしてあなたがそれを定義しようとした場合、あなたが宣言しているため、コンパイラは、あなたがそのようなものを持っていないこと、@disable
ラインで、アウトエラーになります。
私はあなたがトラブルになる可能性があるリソースを失いソースが必要な場合だと思います。しかし、それはほとんどのケースでは問題ではないかもしれないので、あなたが複数の所有者を心配する必要がしばしばを避けることができGC'edされます。