new与operator new

    c++中有两种new,一种是new操作符另一种是operator new。new操作符是c++语言级别支持的,类似于sizeof操作符,它会做两件事:分配足够的内存以容纳对象,然后调用构造函数初始化上一步所分配的内存。operator new就是new操作符进行第一步操作调用的函数,它只为对象分配原始内存,类似于malloc。
下面详细介绍operator new函数:
(1)void* operator new(size_t size);这是operator new函数的原型,我们可以重载之~,但是重载函数的第一个参数必须是size_t类型。可以手动调用这个函数类似这样:int *a = (int*)operator new(sizeof(int));一般不需要手动调用。
(2)operator new 的一个特殊的版本——replacement new
它的原型是 void*operator new(std::size_t ,void *);该运算符是在已分配的内存上重新构造对象,因为不分配内存,所以不必担心分配失败。唯一的工作是调用构造函数

示例1:
# include <new>
# include <iostream>
using namespace std;
void main()
{ 
    char * p = new(nothrow) char [4]; //这里调用的是operator new的不抛出异常的版本
    if (p == NULL)
    { 
        cout < <“allocte failed” < <endl; 
        exit( -1 ); 
    }
    // ...
    long * q = new(p)long(1000);
    delete [ ]p; //只释放 p,不要用q释放。
} 
p和q仅仅是首址相同,所构建的对象可以类型不同。 所“放置”的空间应小于原空间,以防不测。当”放置new”超过了申请的范围,Debug版下会挂机,但Release版竟然能运行而不出错!
该运算符的作用是:只要第一次分配成功,不再担心分配失败。

示例2:
# include <new>
# include <iostream>
using namespace std;
void main()
{ 
    char * p = new(nothrow) char [100];
    if (p == NULL)
    { 
        cout < <“allocte failed” < <endl; exit( -1 );     
    }
    long * q1 = new(p)long(100);
    // 使用q1 ...
    int * q2 = new(p) int[100/sizeof(int) ];
    // 使用q2 ...
    ADT * q3 = new(p) ADT[100/sizeof(ADT) ];
    // 使用q3 然后释放对象 ...
    delete [ ]p; //只释放空间,不再析构对象。
}


示例3:

注意:使用该运算符构造的对象或数组,一定要显式调用析构函数,不可用delete代替析构,因为placement new 的对象的大小不再与原空间相同。
# include <new>
# include <iostream>
using namespace std;
void main()
{ 
    char * p = new(nothrow) char [sizeof(ADT)+2];
    if (p == NULL)
    { 
        cout < <“allocte failed” < <endl; exit( -1 ); 
    }
    // ...
    ADT * q = new(p) ADT;
    // ...
    // delete q; // 错误
    q-> ADT::~ADT(); //显式调用析构函数,仅释放对象
    delete [ ]p; //最后,再用原指针来释放内存.
} 
placement new 的主要用途就是可以反复使用一块已申请成功的内存空间。这样可以避免申请失败的徒劳,又可以避免使用后的释放。
特别要注意的是对于 placement new 绝不可以调用的delete, 因为该new只是使用别人替它申请的地方(只是个租房户,不是房主。无权将房子卖掉)。释放内存是nothrow new的事,即要使用原来的指针释放内存

(3)operator new 的另两个版本
void*operator new(std::size_t)throw(std::bad_alloc); //失败抛出异常,这是默认版本,new操作符就是调用这个
void operator delete( void *) throw();

void*operator new(std::size_t,const std::nothrow_t & )throw(); //不抛出异常,失败返回NULL
void operator delete( void *) throw();
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值