3

私は次のコードを持っています:

struct foo {};
void bar(foo *d) {
  new(d) foo(*d);
}

式は、new(d) foo(*d)によって指されたオブジェクトを変更しdないままにしますか? より具体的には、クラスfooとその中に再帰的に含まれるすべてのオブジェクトに自明なコピーコンストラクターしかない場合、上記はnew(d) foo(*d)当てはまります*dか? そうでない場合はnew、コピー コンストラクターを呼び出す前に、まずメモリをゼロにします。C++ 言語にそのような節はありますか?

編集: 誰かがこれをやりたいと思うのには、重要な理由があります。たとえば、CPU メモリから GPU メモリに、アドレス空間全体でオブジェクトをコピーすることを検討してください。そのための 1 つの解決策は、オブジェクトをバイト単位で処理することです。これは多くの場合に機能します。クラスに仮想メソッドがある場合、バイトごとのコピーによって vtable ポインターがコピーされ、これが一部の CPU メモリを指します。オブジェクトで上記の式を使用してnew(d) foo(*d)、コンパイラに vtable ポインタを強制的にリセットさせることができます。

4

6 に答える 6

1

これは未定義の動作だと思います。オブジェクトが格納されているメモリが別の目的で使用されると、オブジェクトの存続期間は終了します。thisポインターが に等しいコピー コンストラクターに入った瞬間dに、元のオブジェクトは (言語に関する限り) 存在しなくなり、コピー コンストラクターにダングリング リファレンスができます。

もちろん、効果がある状況はさらに簡単です~foo()。この場合、未定義の動作のさらに別の理由があります。

于 2012-05-07T23:02:11.090 に答える
0

オブジェクトのコピーコンストラクターを、それ自体をコピー元として呼び出していることに注意してください。私はこれが単純に狂ってしまうことを期待します。知るか。規格には、何かを期待するようなものは何もありません。

于 2012-05-07T22:55:09.173 に答える
0

Placement new の唯一の仕事は、まだ初期化されていないオブジェクト用に確保されたメモリ上でコンストラクタを実行することです。代わりにコンストラクターを手動で呼び出した場合に得られることよりも、それ以上のこともそれ以下のこともありません (ただし、それは不可能です)。

于 2012-05-07T22:50:17.910 に答える