通常の関数呼び出しだけにできないのはなぜですか? 新しいのは基本的に次のとおりです。
malloc(sizeof(Foo));
Foo::Foo();
削除中
Foo:~Foo();
free(...);
では、なぜ new/delete は通常の関数ではなく独自の構文を持つことになるのでしょうか?
通常の関数呼び出しだけにできないのはなぜですか? 新しいのは基本的に次のとおりです。
malloc(sizeof(Foo));
Foo::Foo();
削除中
Foo:~Foo();
free(...);
では、なぜ new/delete は通常の関数ではなく独自の構文を持つことになるのでしょうか?
ここにそれを突き刺します:
newオペレーターが関数を呼び出しますoperator new()。同様に、delete演算子はoperator delete()関数を呼び出します (配列バージョンについても同様です)。
では、これはなぜですか?ユーザーはオーバーライドを許可されていますoperator new()が、オペレーター (キーワード)は許可されていないためです。new独自のアロケータを定義するためにオーバーライドoperator new()(および削除) しますが、適切なコンストラクタとデストラクタを呼び出す責任はありません (またはそのことについては許可されていません)。newこれらの関数は、キーワードが検出されると、コンパイラによって自動的に呼び出されます。
この二分法がなければ、ユーザーは関数をオーバーライドできますoperator new()が、コンパイラはこれを特別な関数として扱い、作成されるオブジェクトに対して適切なコンストラクターを呼び出す必要があります。
オーバーロードoperator newしoperator deleteて、独自の割り当てセマンティクスを提供できます。これは、既定のヒープ アロケーターの動作をバイパスする場合に役立ちます。たとえば、小さい固定サイズのオブジェクトの多数のインスタンスを割り当ておよび割り当て解除する場合、そのメモリ管理にプール アロケータを使用することができます。
andを他の演算子newとdelete同様に明示的な演算子にすることで、C++ の演算子のオーバーロード メカニズムを使用してこの柔軟性を簡単に表現できます。
スタック上のオブジェクトの場合auto、割り当て/コンストラクターの呼び出しと割り当て解除/デストラクタの呼び出しは、基本的に要求に応じて透過的です。:)
関数でコンパイル時の型安全性を提供する方法がないためです (malloc() は void* を返します、覚えておいてください)。さらに、C++ は、割り当てられているが初期化されていないオブジェクトが浮遊する可能性をわずかでも排除しようとします。また、デフォルトのコンストラクターを持たないオブジェクトもあります。これらの場合、コンストラクターの引数をどのように関数に与えますか? このような関数では、特殊なケースの処理が多すぎます。言語機能への昇格が容易になります。したがって、演算子は新しいです。
'new/delete' は C++ 言語のキーワード ('for' や 'while' など) であり、malloc/calloc は標準 C ライブラリの関数呼び出し ('printf' や 'sleep' など) です。非常に異なる獣であり、類似した構文が許す以上のものです。
主な違いは、'new' と 'delete' が追加のユーザー コード (具体的にはコンストラクターとデストラクター) をトリガーすることです。すべての malloc が行うことは、ユーザーが使用できるようにメモリを確保することです。単純な単純な古いデータ (float や int など) 用にメモリを確保する場合、'new' と 'malloc' は非常によく似た動作をします。しかし、クラスのスペースを要求すると、「new」キーワードがメモリを確保し、コンストラクタを呼び出してそのクラスを初期化します。大きな違い。
C++ に大なりの別の構文があるのはなぜですか? 通常の関数呼び出しだけにできないのはなぜですか?
greaterThan(foo, bar);