1

ゲームエンジンをJavaからC++に移植中です。私は今、メモリ管理について心配する必要があるので、カスタムメモリアロケータについて多くの研究を行ってきました。このトピックについて私が読んだすべての記事には、newanddelete演算子をオーバーロードする必要があると書かれています。ただし、これらのオーバーロードされた演算子は通常、メモリ割り当てを処理するカスタム関数に委任して呼び出すだけです。さらに、次のようなマクロが一般的に使用されます。

#define New(className, size, description) customNew(className, size, description, __FILE__, __LINE__)

newオーバーロードされた演算子を使用することはなく、カスタムメソッドを呼び出すだけです。ファイル名と行番号をうまく取得できるので、マクロがどのように役立つかは理解していますが、なぜオーバーロードするnewのか、コードでは演算子ではなくdeleteマクロを使用するだけです。New

newまた、カスタムアロケータが説明、ファイル名、行番号などの追加情報を知りたい場合は、デフォルトをオーバーライドする(オーバーロードしない)ことはやや無意味に思えます。の標準的な呼び出しに関する情報を知ることはできず、意味のある方法でnewそれを私たちに委任することもできません。customNew

これらの演算子をオーバーロードしてオーバーライドすることの大きなメリットが何であるかがわかりません。

私には、次のように呼びかけているようです。

customNew(className, size, desc, file, line);

オーバーロードを呼び出すよりも直感的ですnew

new (size, desc, file, line) className();

最後に、オーバーライドしてオーバーロードする場合、それを行うのに最適な場所はどこですか?クラスごとにそれを行うことは、厄介な退屈です。名前空間で実行できますか?サブシステムごとに別々のプロジェクトを作成して、それらを個別に保守できるようにする予定です。プロジェクト全体、そしてゲームのプロジェクト内でのオーバーライドとオーバーロードをどのように促進しますか?私のC++n00bishnessを許してください。久しぶりです。

4

2 に答える 2

3

これらの演算子をオーバーロードしてオーバーライドすることの大きなメリットが何であるかがわかりません。

明らかなポイントがあります:あなたはそれを逃れることはできません(仕事なしではありません)。

すべてのメモリ割り当てを1つの場所で実行したい場合、誰かがそれを台無しにするのに必要なのはこれだけです。

new Foo();

newただし、演​​算子とをグローバルにオーバーライドする場合はdelete、より多くの作業を行う必要があります。

void * ptr = malloc(sizeof(Foo));
new(ptr) Foo;

また、C ++プログラマーの大多数が、デフォルトで使用するandnewに慣れているという点もありdeleteます。あなたが彼らに機能を使うことを要求するならば、それはあなたが彼らに教えなければならないものになり、彼らは学ばなければなりません。そして、彼らが間違いを犯して標準的な方法を使用する場合は、上記を参照してください。

ああ、それから構文があります:

customNew(className, size, desc, file, line);

それはうまくいきません。これによりメモリが割り当てられる場合がありますが、型は作成されません。と違いはありませんmalloc。つまり、まさにその名前は嘘です。それは「新しい」ものではありません。割り当てているだけです。

正しく行うには、C++11可変個引数テンプレートとインプレース構築を使用する必要があります。

template<typename T, typename ...Args>
T *customNew<T>(const char *className, const char *desc, size_t file, size_t line, Args&&... args)
{
  void* ptr = allocate_memory(className, sizeof(T), desc, file, line);
  return new(ptr) T(std::forward<Args>(args)...);
}

個人的には、構文はバージョンnew(...) T(...)よりもはるかにクリーンだと思います。customNew<T>(...)どのパラメーターがアロケーターに送られ、どのパラメーターがタイプ自体に送られるかは明らかです。それは確かにより標準的です。

しかし、どこでグローバルなnewをオーバーライドして削除しますか

グローバルに。グローバル名前空間の場合と同様です。オーバーロードをヘッダーのどこかに貼り付けて、どこにでも含めます。

于 2012-07-18T21:50:15.613 に答える
2

You might have a general purpose allocator that is garbage collected, aligned, and has a maximum size limit, which might be possible constraints of your spec. If you use external code that makes use of new/delete, you could redirect requests to this allocator as some kind of low-level/system memory space.

Also, articles I read often go after the global operators as a start. Here is a good stackoverflow post on the subject.

于 2012-07-18T20:45:21.990 に答える