13

次の構成が表示されます。

  • new XXコンストラクターがスローした場合、メモリを解放します。

  • operator new()過負荷になる可能性があります。

演算子 new オーバーロードの標準的な定義はvoid *operator new(size_t c, heap h)、対応するoperator delete.

最も一般的な演算子 new のオーバーロードは、placement new です。void *operator new(void *p) { return p; }

ほとんどの場合delete、placement に指定されたポインターを呼び出すことはできませんnew

これは 1 つの疑問につながります:Xコンストラクターがスローし、オーバーロードnewが使用された場合、メモリはどのようにクリーンアップされますか?

4

5 に答える 5

5

delete基本的に、その演算子に対応する演算子がなければnew何もしません。配置 new の場合も、対応する配置削除演算子はノーオペレーションであるため、何も行われません。例外は迂回されません。例外はそのまま続行されるため、 new の呼び出し元には、割り当てられたメモリを解放する機会 (および責任) があります。

配置 new は、別の方法で取得したメモリにオブジェクトを配置するために使用されるため、それと呼ばれます。メモリーは new オペレーターによって獲得されなかったので、delete オペレーターによって解放される可能性は低いでしょう。実際には、(少なくとも C++03 以降では) プレースメント new 演算子 (prototypeoperator new(size_t, void*)または delete ( operator delete(void*, void*)) を持つ) を置き換えることは許可されていないため、問題は意味がありません。提供されたプレースメント new 演算子はその 2 番目の引数を返し、提供された配置の削除演算子はノーオペレーションです。

その他のnewanddelete演算子は、グローバルに、または特定のクラスに対して置き換えることができます。カスタムnew演算子が呼び出され、コンストラクターが例外をスローし、対応するdelete演算子がある場合、その削除演算子が呼び出されて、例外が伝播される前にクリーンアップされます。deleteただし、対応する演算子がなくてもエラーにはなりません。

于 2013-10-30T15:51:01.500 に答える
1

コンストラクターが例外をスローすると、対応する削除が呼び出されます。スローしたクラスに対してデストラクタは呼び出されませんが、コンストラクタが正常に呼び出されたクラスのコンポーネントはすべて、デストラクタが呼び出されます。

于 2013-10-30T15:50:21.363 に答える
1

'placement new' は new のオーバーロードされたバージョンではありませんが、演算子 new のバリアントの 1 つであり、オーバーロードできないものでもあります。

新しい演算子のリストと、それらのオーバーロードがどのように機能するかについての説明を参照してください

配置 new の使用時にコンストラクターが例外をスローした場合、コンパイラーは使用された new 演算子を認識し、placement delete を呼び出します。

于 2013-10-30T15:51:53.380 に答える
0

new-expressionの一部として構築されているオブジェクトの構築が失敗すると、対応する解放関数 (存在する場合) が呼び出されます。例えば

new X;

次の割り当て/割り当て解除関数のペアを使用します。

void * operator new(std::size_t);
void operator delete(void *);

同様に、次の形式のプレースメント new について

new(&a) X;

operator newoperator delete関数の配置バージョンが使用されます。

void * operator new(std::size_t, void *);
void operator delete(void *, void *);

最後の関数は、意図的にアクションを実行しないことに注意してください。

于 2013-10-30T15:53:48.497 に答える