New演算子
newやnew[]が記憶域を確保できなかった場合、既定では例外クラス型std::bad_alloc(またはその派生クラス)のインスタンスが投げられるが、カスタマイズすることも可能である。
newハンドラ
newハンドラは、既定のnewおよびnew[]演算子関数で記憶域確保に失敗した場合に呼ばれるコールバック関数であり、std::set_new_handler関数で登録できる。当時まだ例外処理がなかったC++で、記憶域確保の失敗をまとめて取り扱うために導入された。
newハンドラでは、例外を投げたり、プログラムを終了させたりするなどのほか、何らかの方法で記憶域に空きを作ることで、newおよびnew[]演算子関数の記憶域確保を成功へ導かせることも可能である。
new演算子とnew[]演算子での記憶域の確保を制御するために、これらの演算子は多重定義が可能である。そうして定義されたnewおよびnew[]演算子関数は、newおよびnew[]演算子での記憶域確保に使用される。そして、deleteおよびdelete[]演算子の記憶域の解放には、deleteおよびdelete[]演算子関数が使用される。
クラス内に設置した場合、そのクラスと派生クラスをnew演算子で作成する際の記憶域の確保に使用される。なおクラス内に置いた場合、staticを指定しなくても、自動的に静的メンバ関数として扱われる (X3014 12.5)。
new hogeという式は次のように実行される。
まず、new演算子関数の名前探索を行う(この例では、hoge::operator newが見つかる)。
sizeof (hoge) の値を引数にしてnew演算子関数を呼び、記憶域確保を行う。
new演算子関数が返したポインタの指す位置をthisポインタとして、コンストラクタを呼び、インスタンスを生成する。
C++では、newあるいはnew[]で記憶域を動的に確保して生成したインスタンスは、不要になったときにそれぞれdeleteあるいはdelete[]演算子で破棄されなければならない。これはC言語においてmalloc関数で確保した領域をfree関数で解放することに相当するが、deleteあるいはdelete[]演算子の場合はメモリ解放の前にデストラクタが呼ばれる点が異なる。ヒープ領域に動的に確保されたメモリは自動的に破棄されることはなく、破棄し忘れたままプログラムを続行するとメモリリークとなる。多くの場合、明示的な破棄を毎回記述することはプログラマの負担となるため、破棄をデストラクタに任せるRAIIパターンが利用される。デストラクタを利用することで例外が発生しても確実に破棄することが可能となる(例外安全)。
従来のC++標準ライブラリにはスマートポインタのクラステンプレートとしてstd::auto_ptrが定義されていたが、C++11では廃止予定となり、代わってstd::unique_ptrやstd::shared_ptrなどが定義された。
動的配列のRAIIとしては、std::vectorクラステンプレートがよく利用される。
C#のnew演算子は、インスタンスを生成・初期化するという意味を持っており、参照型を対象とする場合はヒープから記憶域を確保するが、値型(構造体や列挙型)を対象とする場合は単に一時的なインスタンス(これはヒープ上に生成されるのではない)を初期化するだけである。
下のコードの場合、少なくとも概念上は、一時的なint型のインスタンスが生成され、それがxへコピーされているという扱いである。
上記は以下と等価である。