new 運算子 (C++)
從可用存放區針對 type-name 的物件或物件陣列配置記憶體,並傳回適用類型、非零物件指標。
注意事項 |
---|
Microsoft C++ 元件擴充功能會提供對 new 關鍵字的支援以加入 vtable 位置項目。如需詳細資訊,請參閱 new (vtable 中的新位置) (C++ 元件擴充功能)。 |
[::] new [placement] new-type-name [new-initializer]
[::] new [placement] ( type-name ) [new-initializer]
備註
如果不成功,new 會傳回零或擲回例外狀況;請參閱 new 和 delete 運算子以取得詳細資訊。 您可以變更這個預設行為,作法是撰寫自訂例外狀況處理常式,並將您的函式名稱當做引數來呼叫 _set_new_handler 執行階段程式庫函式。
如需如何在 Managed 堆積上建立物件的詳細資訊,請參閱 gcnew。
當使用 new 來配置 C++ 類別物件的記憶體時,會在配置記憶體之後呼叫物件的建構函式。
使用 delete 運算子解除配置以 new 運算子配置的記憶體。
下列範例會先配置然後再釋放大小為 dim 乘以 10 個字元的二維陣列。 配置多維陣列時,第一個維度以外的所有維度都必須是判斷值為正值的常數運算式;最左邊的陣列維度可以是任何判斷值為正值的運算式。 使用 new 運算子配置陣列時,第一個維度可以是零 (new 運算子會傳回唯一指標)。
char (*pchar)[10] = new char[dim][10];
delete [] pchar;
type-name 不能包含 const、volatile、類別宣告或列舉宣告。 因此,下列運算式是不合法的:
volatile char *vch = new volatile char[20];
new 運算子無法配置參考類型,因為這些類型不是物件。
new 運算子無法用來配置函式,但是可以用來配置函式的指標。 下列範例會配置然後再釋放含七個傳回整數之函式指標的陣列。
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 運算子的新位置形式 (即除了配置大小之外,還有其他引數的形式),則編譯器不支援可在建構函式擲回例外狀況時使用的位置形式 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;
}