一、plain new就是最普通的new的,动态创建一个对象或数组,基本用法如下:
class A
{
int m_v;
public:
A() {}
A(int v) : m_v(v) {}
A(double v) : m_v(ceil(v)) {}
};
A* p1 = new A; //非必要情况不会调用合成的构造函数
A* p2 = new A(); //必然调用构造函数,如果没有,调用合成构造函数
A* p3 = new A(3); //调用int参数构造
A* p4 = new A(3.1); //调用double类型构造
A* p5 = new A[2]; //分配2个元素数组,非必要不初始化
A* p6 = new A[2](); //分配2个元素,初始化
A* p7 = new A[2](3); //非法调用,动态分配数组不能指定带参数的构造函数
//
delete p1;
delete p2;
delete p3;
delete p4;
delete [] p5;
delete [] p6;
关于new A和new A()区别,可以参考一个讲的细节的文章:http://blog.csdn.net/eldn__/article/details/41963727
二、nothrow new不抛异常的new
如果内存不足,new默认会抛异常std::bad_alloc,大部分情况我们希望内存不足时立即停止,否则在动态分配内存时,还需要增加非常多的分支,处理逻辑复杂N倍。但是,如果有时候,我们是有办法解决内存不足的,比如等待一会儿,尤其是服务端程序比较常见,这个时间, 我们希望自己来处理内存不足。在大块内存申请上,更容易遇到。首先想到的可能是用try catch,代码如下
try {
p1 = new A();
} catch (std::bad_alloc) {
//等待并重试
}
其实,nothrow new就是解决这个场景的,如果内存不足,返回nullptr而不是抛异常,用法如下:
p1 = new(nothrow) A;
if(p1 == nullptr)
;//等待并重试
三、placement new,直译“只放置的new",这个new并不分配内存,仅初始化,非常有用,我们可以显示的去重复调用构造函数,是内存池的基础,allocator实现必然用到。多一个参数传递一个内存空间,不要求大小一致,只要大于对象即可,这样,大对象的内存资源是可以复用给小对象的。用法如下:
p1 = new (buf) A[2];
p1->~A();
delete p1; //core
如上,复用的new,必须不能被delete,否则core异常,而是要显示的调用析构函数。
发现一个讲的不错的文章,参考:http://www.jb51.net/article/41524.htm