6

AngelScriptエンジンに接続したクラスがいくつかあります。このエンジンは、オブジェクトを割り当てるために興味深い方法を使用します。必要な量のメモリを割り当てます(おそらくでmalloc())。作成者がこのような構造を使用してこのメ​​モリにオブジェクトを作成することを提案する場合:

static void Constructor(ObjectType *thisPointer)
{
    new(thisPointer) ObjectType();
}

オブジェクトを破棄するには、次のようにコーディングします。

static void Destructor(ObjectType *thisPointer)
{
     thisPointer->~ObjectType();
}

いくつか質問があります。

  • このようにデストラクタを使用するのは正しい方法ですか?(Eclipseはこれをバグと判断します)私が理解できる限り、このコードはメモリの割り当てを解除せずにデストラクタを呼び出す必要があります(呼び出しfree()
  • この構造の代わりに(またはそのようなものを)使用することは可能delete(thisPointer)ですか?それは同等ですか?(少なくともこのコードは、コンパイルおよび実行時にエラーを発生させません)
  • メモリの割り当てを解除せずにデストラクタを呼び出す他の方法はありますか?

前もって感謝します。

4

2 に答える 2

12

ここでC++は少し誤解を招きます:

構築とメモリ管理は、実際には完全に無関係なプロセスであり、C++は便利なように一緒に機能newdeleteます。

ただし、C ++には、既存のメモリでコンストラクタを呼び出すための専用の構文が実際にはありません。これを行うには、実際にはまったく従来とは異なる「配置new」構文を使用する必要があります。つまり、メモリを割り当てません。new

一方、オブジェクトのデストラクタを呼び出す構文がありますそして、あなたのコードはそれを正しく使用します。いいえ、使用deleteすることは同等ではありません。デストラクタを呼び出すことに加えて、メモリを解放します。

std::allocatorこれを、メソッド(および対応するセマンティクス)を持つクラスと比較してください。

  • allocate(== ::operator new(sizeof T)
  • deallocate(== ::operator delete(&x)
  • construct(== new (&x) T()
  • destroy(== x.~T()

これらは、オブジェクトのライフタイムサイクルのさまざまな側面に正確に対応しています。

于 2012-05-24T13:13:15.677 に答える
5

このようにデストラクタを使用するのは正しい方法ですか?

はい。あなたはplacement-newを使用してオブジェクトをインプレースで構築したので、明示的なデストラクタ呼び出しでオブジェクトを破棄する必要があります(重要なデストラクタがあると仮定します)。

この構造の代わりに(またはそのようなものを)使用することは可能delete(thisPointer)ですか?それは同等ですか?

いいえ。メモリを空きストアに解放するdeleteために使用しようとします。これは、通常の式(またはの明示的な使用)operator delete()で割り当てられた場合にのみ有効です。newoperator new()

メモリの割り当てを解除せずにデストラクタを呼び出す他の方法はありますか?

あまり。デストラクタを呼び出すことは、デストラクタを呼び出すための最も明確で簡単な方法です。

于 2012-05-24T13:15:52.463 に答える