new 演算子 (C++)
フリー ストアから type-name のオブジェクトまたはオブジェクトの配列にメモリを割り当て、オブジェクトへの適切に型指定されたゼロ以外のポインターを返します。
注意
Microsoft C++ Component Extensions では、new キーワードによる vtable スロット エントリの追加がサポートされています。詳細については、「new (vtable の新しいスロット) (C++ コンポーネント拡張)」を参照してください。
[::] new [placement] new-type-name [new-initializer]
[::] new [placement] ( type-name ) [new-initializer]
解説
この処理に失敗した場合、new はゼロを返すか、例外をスローします。詳細については、「new 演算子と delete 演算子」を参照してください。 カスタム例外処理ルーチンを作成し、_set_new_handler ランタイム ライブラリ関数を呼び出して、その引数として関数名を渡すことにで、この既定の動作を変更できます。
マネージ ヒープにオブジェクトを作成する方法については、「gcnew」を参照してください。
new を使用してメモリを C++ クラス オブジェクトに割り当てると、メモリの割り当て後に、そのオブジェクトのコンストラクターが呼び出されます。
new 演算子を使用して割り当てたメモリを解放するには、delete 演算子を使用します。
次の例では、サイズ dim × 10 の文字の 2 次元配列を割り当てた後、解放します。 多次元配列を割り当てるときに、最初の次元を除くすべての次元は、正の値に評価される定数式であることが必要です。配列の一番左の次元は、正の値に評価される任意の値でかまいません。 new 演算子を使用して配列を割り当てるとき、最初の次元はゼロでかまいません。new 演算子は一意のポインターを返します。
char (*pchar)[10] = new char[dim][10];
delete [] pchar;
type-name に const、volatile、クラス宣言、または列挙体宣言を含めることはできません。 したがって、次の式は無効です。
volatile char *vch = new volatile char[20];
new 演算子は参照型を割り当てません。それらがオブジェクトでないためです。
new 演算子は、関数の割り当てには使用できませんが、関数へのポインターの割り当てには使用できます。 次の例では、整数を返す関数への 7 個のポインターの配列を割り当てた後、解放します。
int (**p) () = new (int (*[7]) ());
delete *p;
余分な引数を付けずに new 演算子を使用し、/GX、/EHa、または /EHs オプションを指定してコンパイルする場合、コンストラクターが例外をスローしたときに delete 演算子を呼び出すコードが、コンパイラによって生成されます。
次の一覧では、new の文法要素について説明します。
placement
new をオーバーロードする場合、追加の引数を渡す方法を指定します。type-name
割り当てる型を指定します。組み込みまたはユーザー定義の型を指定できます。 型の指定が複雑な場合には、かっこで囲むことでバインディング順を強制的に適用できます。initializer
初期化されたオブジェクトの値を指定します。 初期化子は配列には指定できません。 new 演算子は、クラスに既定のコンストラクターがある場合のみ、オブジェクトの配列を生成します。
使用例
次のコード例では、文字配列と CName クラスのオブジェクトを割り当てた後、解放します。
// expre_new_Operator.cpp
// compile with: /EHsc
#include <string.h>
class CName {
public:
enum {
sizeOfBuffer = 256
};
char m_szFirst[sizeOfBuffer];
char m_szLast[sizeOfBuffer];
public:
void SetName(char* pszFirst, char* pszLast) {
strcpy_s(m_szFirst, sizeOfBuffer, pszFirst);
strcpy_s(m_szLast, sizeOfBuffer, pszLast);
}
};
int main() {
// Allocate memory for the array
char* pCharArray = new char[CName::sizeOfBuffer];
strcpy_s(pCharArray, CName::sizeOfBuffer, "Array of characters");
// Deallocate memory for the array
delete [] pCharArray;
pCharArray = NULL;
// Allocate memory for the object
CName* pName = new CName;
pName->SetName("Firstname", "Lastname");
// Deallocate memory for the object
delete pName;
pName = NULL;
}
仮引数付きの new 演算子、つまり割り当てサイズ以外の引数を伴う形式の new 演算子を使用する場合、コンストラクターが例外をスローしたときの仮引数付きの delete 演算子は、コンパイラによってサポートされていません。 次に例を示します。
// expre_new_Operator2.cpp
// C2660 expected
class A {
public:
A(int) { throw "Fail!"; }
};
void F(void) {
try {
// heap memory pointed to by pa1 will be deallocated
// by calling ::operator delete(void*).
A* pa1 = new A(10);
} catch (...) {
}
try {
// This will call ::operator new(size_t, char*, int).
// When A::A(int) does a throw, we should call
// ::operator delete(void*, char*, int) to deallocate
// the memory pointed to by pa2. Since
// ::operator delete(void*, char*, int) has not been implemented,
// memory will be leaked when the deallocation cannot occur.
A* pa2 = new(__FILE__, __LINE__) A(20);
} catch (...) {
}
}
int main() {
A a;
}