0

初心者の質問:

Class Quote {
    public:
    /* ..... */

    virtual Quote* clone() const & {return new Quote(*this);}

    virtual Quote* clone() && {return new Quote(std::move(*this));} // (***)

    /* ..... */
}

newによって割り当てられたオブジェクトはフリーストアにあります。*これはclone()を呼び出すオブジェクトであり、必ずしも動的に割り当てられたオブジェクトではありません。

移動元オブジェクトと移動先オブジェクトが異なるメモリ領域にある場合、移動メカニズムはどのように機能しますか? それとも、彼らは本当に別の地域にいることはなく、何かが足りないのでしょうか?

私が理解していることから、移動コンストラクターは、移動元オブジェクトのデータ/メモリ部分にリンクする新しいオーバーヘッドを作成します。データ自体は移動/変更されません。上記の場合、これはどのように機能しますか?それが同じように機能する場合、新しい実行後、動的に割り当てられたオブジェクトがフリーストアの外にあることはありませんか (どこにあります? ) std::move()がどのように/なぜ機能するのか正確にはわかりませんが、名前付きオブジェクトへの右辺値参照を強制的に返し、そのオブジェクトから移動できるようにします。

4

2 に答える 2

1

私が理解していることから、移動コンストラクターは、移動元オブジェクトのデータ/メモリ部分にリンクする新しいオーバーヘッドを作成します。データ自体は移動/変更されません。

違います。典型的なムーブ コンストラクター (ムーブ コンストラクターは、クラス ライターがやりたいことを実際に実行できるため、典型的なものを強調します) は、別のオブジェクトがリモートで所有するリソース(動的に割り当てられた配列など)を、ハンドルを再割り当てすることによって(ポインター動的に割り当てられた配列に)

リソースがリモートで所有されていると言うとき、それは実際にはクラスのデータ メンバーではないことを意味します。ただし、ハンドルクラスのデータ メンバーです。ハンドルはリソースを参照します。移動先オブジェクトと移動元オブジェクトには、異なるアドレスとデータ メンバがあります。それらのデータは、実際にはクラスの一部ではなく、ハンドルによって参照されるため、効率的に移動できます。リソースとは異なり、ハンドルは小さく、安価にコピーできます。「移動」とは、実際にはソース オブジェクトから宛先オブジェクトにハンドルをコピーし、ソース オブジェクトのハンドルを無効にして、そのデストラクタがリソースを破棄しないようにすることです。

移動元オブジェクトと移動先オブジェクトが異なるメモリ領域にある場合、移動メカニズムはどのように機能しますか?

(繰り返しますが、私は典型的なムーブ コンストラクターについて話しているのです) それは無関係です。たまたまどこに保存されていても、同じメモリ レイアウトを保持しています。ハンドルはまったく同じように変更されます。移動先オブジェクトのデストラクタが呼び出されると、リソースが解放されます (そのオブジェクトも移動元でない限り)。これは、オブジェクトがスタック上にある場合はオブジェクトがスコープ外になったとき、またはdeleteフリーストア上にある場合はオブジェクトを指すポインターで呼び出されたときのいずれかを意味します。(他にも可能性はありますが、これらの 2 つが明らかに最も一般的です)

于 2013-11-15T09:30:59.930 に答える
0

1 回の移動ですべてが移動するわけではありません。たとえば、int やポインターなどの組み込みデータ型は移動できず、コピーすることはできます。移動は純粋なセマンティクスです。最良の例は astd::vectorまたは astd::stringです。どちらも通常、動的に割り当てられたメモリとその他の変数へのポインタを含んでいます。このメモリは意味的にオブジェクトに属していvectorます。つまり、メモリを解放する必要があり、その内容を変更する可能性があり、それを制御でき、そうする唯一のメモリです。一般的な用語は、「割り当てられたメモリの所有権vectorを持っている」です。 ここで、ベクターをコピーすると、オリジナルはその所有権を保持し、コピーは独自のメモリを割り当てる必要があります。逆に移動すると
ベクトルの場合、移動によって構築された新しいベクトルは、割り当てられたメモリを盗むことができ、元のベクトルがかつて所有していたリソースの所有権を引き継ぎます。これは、元のベクトルが範囲外に出ようとしており、そのリソースをもう必要としないために実行できます。
ただし、移動された実際のデータ メンバーvector自体は移動されません。それらはポインターであり、場合によっては int であるため、コピーすることしかできません。それが完了すると、元のポインターと int は、割り当てられたメモリの所有権を意味的に終了するように変更されます。

要するに、移動はセマンティックなものであり、より低い技術レベルでは、ほとんどがコピーであり、オリジナルをゼロに設定します。

于 2013-11-15T10:05:41.623 に答える