新运算符(C++)
从可用存储为对象分配内存或数组 类型名称 该对象并返回适当地类型化,非零指向对象。
[::] new [placement] new-type-name [new-initializer]
[::] new [placement] ( type-name ) [new-initializer]
备注
如果不成功, 新 返回零或引发异常;请参见 新建和删除运算符 有关更多信息。您可以通过编写自定义异常处理的实例并调用使用函数名的 _set_new_handler 运行库函数更改此默认行为作为其参数。
有关如何创建在托管堆上的对象的信息,请参见 gcnew。
当 新 用来指定 c. C++ 类对象的内存时,对象的构造函数调用,在赋值后内存。
使用 删除 运算符释放内存分配与 新 运算符。
下面的示例以 10. 分配释放范围 dim 字符一个二维数组。在将多维数组时,除第一的所有维度必须是计算为正值的常数表达式;最左侧的数组维度进行计算结果为一个正值的任何表达式。在将数组使用 新 运算符,第一个维可为零 )时 新 运算符返回一个指针。
char (*pchar)[10] = new char[dim][10];
delete [] pchar;
类型 名称不能包含 const、 volatile、类、声明枚举声明。因此,下面的表达式是非法的:
volatile char *vch = new volatile char[20];
,因为它们不是对象, 新 运算符未将引用类型。
新 运算符不能用于分配函数,但是,它可用于指针分配给函数。下面的示例指定释放数组七指向返回整数的功能。
int (**p) () = new (int (*[7]) ());
delete *p;
如果使用运算符 新 ,而不需要任何额外的参数,并使用进行编译 /GX、 /EHa或 /EHs 选项,编译器将生成调用运算符的代码 删除 ,如果构造函数引发异常。
下面的列表描述 新的语法元素:
位置
,如果您重载 新,通过附加参数方式。类型名称
指定要分发的类型;它可以是内置或用户定义的类型。如果类型规范是复杂的,它可能由括号括起来强制顺序绑定。初始值设定项
用于初始化的对象的值。初始值设定项不能指定数组的。,仅当类具有默认构造函数, 新 运算符将创建一些对象。
示例
下面的代码示例将一个字符数组和类 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;
}
如果使用 新 运算符的放置新窗体,带参数的形式和分配范围之外,编译器不支持 删除 运算符的放置形式,如果构造函数引发异常。例如:
// 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;
}