new的类型
有三种类型的new,名字都是new,用起来也都跟分配内存有关系,分别是plain new , nothrow new和 placement new。看如下代码:
MyClass * p=new MyClass;
这里的new实际上是执行如下3个过程(这三个过程都在一个new operator中完成):
1. 调用malloc/heap_alloc分配内存 ;2. 调用构造函数生成类对象;3. 返回相应指针。
operator new就像operator+一样,是可以重载的,但是不能在全局对原型为void operator new(size_t size)这个原型进行重载,一般只能在类中进行重载,也可以重载全局的operator new,来实现对程序所有的new有统一的行为。nothrow operator new是跟plain new同等地位的,也是可以重载的。如果类中没有重载operator new,那么调用的就是全局的::operator new来完成堆的分配。同理,operator new[]、operator delete、operator delete[]也是可以重载的,一般你重载的其中一个,那么最好把其余的三个都重载一遍。
placement new 不一样的地方就是它不能被重载, 而new 和nothrow new是可以的。
new:
{ // try to allocate size bytes
void *p;
while ((p = malloc(size)) == 0)
if (_callnewh(size) == 0)
{ // report no memory
static const std::bad_alloc nomem;
_RAISE(nomem);
}
return (p);
}
nothrow new
_THROW0()
{ // try to allocate count bytes
void *p;
_TRY_BEGIN
p = operator new(count);
_CATCH_ALL
p = 0;
_CATCH_END
return (p);
}
placement new
{ // construct array with placement at _Where
return (_Where);
}
标准C++ new失败后抛出标准异常std::bad_alloc异常,在一定的环境下,返回一个NULL指针来表示一个失败依然是一个不错的选择。C++标准委员会意识到这个问题,所以他们决定定义一个特别的new操作符版本,这个版本返回0表示失败。于是设计了nothrow new。他们的区别就是nothrow new失败时不抛出异常,而是返回NULL。再看看nothrow new的原型:
void * __CRTDECL operator new(size_t count, const std::nothrow_t&)
nothrow_t
Type of the nothrow constant.
This is a type specifically designed to overload the dynamic memory allocation operator functions operator new, operator new[] , operator delete and operator delete[] .
It is an empty class defined in the <new> header. This header also defines the standard constant nothrow, which is a value of this type specifically designed to call the overloaded operator functions.
Nothrow constant
This constant value is used as an argument for operator new and operator new[] to indicate that these functions shall not throw an exception on failure, but return a null pointer instead.
bad_alloc
Type of the exceptions thrown by the standard definitions of operator new and operator new[] when they fail to allocate the requested storage space.
This class is derived from exception.
new_handler
typedef void (*new_handler)();
Type of new handler function
This is a typedef of a void function with no parameters, used as the argument and return type in function set_new_handler.
A new handler function is a function that is called by the standard definition of functions operator new or operator new[] when they are not successful allocating memory.
set_new_handler
new_handler set_new_handler (new_handler new_p) throw();
Sets new_p as the new handler function.
The new handler function is the function that is called by functions operator new or operator new[] when they are not successful in an attempt to allocate memory.
The new handler function can make more storage available for a new attempt to allocate the storage. If, and only if, the function succeeds in making more storage avaible, it may return. Otherwise it shall either throw a bad_alloc exception (or a derived class) or terminate the program with cstdlib's abort or exit functions.
If the new handler function returns (i.e., it made more storage available), it can be called again if the operator new or operator new[] function is again not successful attempting to allocate the storage. This may repeat itself until either the allocation is successful or thehandler function fails.
使用new时的初始化
在使用new分配内存单元时,一般希望新分配的单元能被初始化为全0。注意以下两条语句:
int *ptrInt1 = new int; //新分配的内存单元里的值是未知
int *ptrInt2 = new int(); //加上括号。新分配的内存单元里的值是全0
这个括号意味着是什么?它是C++中一个不太引人注意的feature,叫做value-initialize。可以参考http://en.cppreference.com/w/cpp/language/value_initialization