5

「placement new」演算子は次のように宣言されます。

void* operator new (std::size_t size, void* ptr) noexcept;

ただし、実際の割り当ては含まれないため、不適切な割り当て例外は排除されますが、ポインターが不適切な場所を指している可能性は依然としてあります。その場合、範囲またはオーバー/アンダーフロー エラーが発生することが予想されますが、発生しません。noexcept代わりに単に実行を終了するように宣言されたという事実は?

また、これは、C++ 11 配置の前に new が直接クラッシュするstd::unexpectedのではなく、スローして処理しようとすることを意味しますか?std::set_unexpected

「念のため」配置の新しいオーバーロードをスローするべきではありませんか?

4

4 に答える 4

3

この関数が何をするかを理解するには、 new-expressionが何をするかを調べる必要があると思います: オブジェクトのストレージを取得するために割り当て関数を呼び出し、割り当て関数が示すメモリ領域にそのオブジェクトを構築します (上記のメモリ領域へのポインタを返すことによって)。

これは、割り当て関数自体によって構築が実行されないことを意味します。割り当て関数には奇妙な名前が付いていoperator newます。

配置-新しい構文を使用して、割り当て関数に追加のパラメーターを指定することができます。

new int(5)        // non-placement form
new(1,2,3) int(5) // placement-form

ただし、placement-newは通常、非常に具体的な new-expressionを参照します。

void* address = ...;
::new(address) int(5) // "the" placement-form

この形式は、すでに割り当てられているメモリ領域にオブジェクトを構築することを目的としています。つまり、コンストラクタを呼び出すだけで、割り当てを実行しないことを目的としています。

その場合のコア言語に特別なケースは導入されていません。代わりに、特別な割り当て関数が標準ライブラリに追加されました。

void* operator new (std::size_t size, void* ptr) noexcept;

no-op ( return ptr;) であるため、オブジェクトのコンストラクターを明示的に呼び出し、特定のメモリ位置で構築できます。この関数呼び出しはコンパイラによって排除できるため、オーバーヘッドは発生しません。

于 2014-11-02T13:42:12.377 に答える