0

「placement new」を使用する場合は、コンストラクタとデストラクタを明示的に呼び出すことをお勧めします。

この場合、クラスの初期化セクションで初期化されたオブジェクトも適切に構築されますか?

デストラクタを明示的に呼び出しても同じですか?メンバー オブジェクトは適切に破棄されますか?

4

2 に答える 2

2

「placement new」を使用する場合は、コンストラクタとデストラクタを明示的に呼び出すことをお勧めします。

コンストラクターには名前がないため ($12.1/1)、「コンストラクターを明示的に呼び出す」というのは正しくありません。

この場合、クラスの初期化セクションで初期化されたオブジェクトも適切に構築されますか?

はい。なぜあなたはそれを疑うのですか?new新しい配置は、オブジェクトを構築するために、オペレーターがメモリを割り当てず、新しい配置で渡したメモリを使用することを意味するだけです。オブジェクトは、渡したメモリ内に構築されます。

デストラクタを明示的に呼び出しても同じですか?メンバー オブジェクトは適切に破棄されますか?

はい。

于 2011-01-07T14:58:19.307 に答える
1

「placement new」を使用する場合は、コンストラクタとデストラクタを明示的に呼び出すことをお勧めします。

私はそうは思わない。デストラクタを明示的に呼び出す必要があると表示されます。

この場合、クラスの初期化セクションで初期化されたオブジェクトも適切に構築されますか?

メモリの供給を除けば、新しい配置の他のすべての側面は、通常の新しいものと同じです。したがって、メモリを動的に割り当てるのではなく、提供されたポインターを使用するだけです。

デストラクタを明示的に呼び出しても同じですか?

(何も感じなければ) 任意のオブジェクトでデストラクタを明示的に呼び出すことができます。ユーザー定義 (またはコンパイラ生成) クラス デストラクタを通常どおり呼び出します。配置 new によって作成されたオブジェクトに対して明示的に行う必要がある理由は、これらのオブジェクトに対して delete を呼び出すことができるからです。これは、delete がオブジェクトが動的に割り当てられたメモリ内に作成されたと想定し、デストラクタが呼び出された後にそのメモリを再利用しようとするためです。

メンバー オブジェクトは適切に破棄されますか?

はい。

new を次のように考えると:

// not real code
template<class T> T* new(void* location = NULL)  (ArgumentsForT)
{
    // If you do not provide location (normal usage)
    // then we allocate some memory for you.
    if (location == NULL)
    {    location = malloc(sizeof(T));   // Use of malloc() is just an example
    }

    ((T*)location)->Constructor(ArgumentsForT);
    return (T*)location;
}

そのため、配置 new は通常の new と同じように機能します。
削除する呼び出しを見る

template<typename T> void delete(T* obj)
{
    if (obj != NULL)
    {
        obj->~T();
        free(obj);
    }
}

ここでの問題は、メモリが new によって割り当てられたのか、それともメモリがユーザーによって割り当てられて new (placement new) に渡されたのかを delete が判断できないことです。そのため、常にメモリ上で free を呼び出します。配置 new を使用した場合は、メモリを動的に割り当てていない可能性があります (または、メモリがまだ別の目的で使用されています)。

char   x[sizeof(T)];  // don't do this (memory may not be aligned correctly).
T*  obj = new (x) T();

delete obj;  // FAIL. The memory was not dynamically allocated.
             //       Delete will try and re-claim this memory for re-yse
             //       Even if the memory is local.

 // This is why on placement new you need to call the destructor
 obj->~T();
于 2011-01-07T15:47:22.210 に答える