C++运算符new的三种方式(林锐-高质量程序设计)

1. plain new 普通new
[cpp]  view plain copy
  1. void*operator new(std::size_t)throw(std::bad_alloc);     
  2. void operator deletevoid *) throw();   
提示:在未标准化时,C++中的运算符总是返回NULL表示分配失败,就像malloc()那样。标准C++修改了new的语义,该运算符在分配失败时将抛出异常,而非返回NULL。使用时要包含 <new>头文件。正常使用new,但要配以异常处理。如:
[cpp]  view plain copy
  1. char *getMemory(unsigned long size)     
  2. {    char * p = new char[size];     
  3.       return p; }     
  4. void main(void )     
  5. {    try{     
  6.         char * p = getMemory(1000000);//可能发生异常     
  7.         // ...     
  8.         delete [ ] p;     
  9.         }     
  10.     catch(const std::bad_alloc & ex)     
  11.     {  cout < <ex.what();    }     
  12. }  
2.nothrow new  不抛掷异常new
[cpp]  view plain copy
  1. void*operator new(std::size_t,const std::nothrow_t & )throw();     
  2. void operator deletevoid *) throw();  
该运算符在分配失败时不抛出异常,而是返回NULL。使用时要包含 <new>头文件。 
该函数的第2形参是 struct nothrow_t {  };它是个全局常对象 const nothrow_t nothrow; 用来作为 new 运算符的标志,以区别前一个new.
3.placement new 放置new
[cpp]  view plain copy
  1. >void*operator new(std::size_t ,void *);     
  2. void operator deletevoid * ,void *);   
该运算符是在已分配的内存上重新构造对象,因为不分配内存,所以不必担心分配失败。唯一的工作是调用对象的构造函数。要包含 <new>头文件。
[cpp]  view plain copy
  1. # include <new>     
  2. # include <iostream>     
  3. void main()     
  4. {  using namespace std;     
  5.     char * p = new(nothrowchar [4];     
  6.     if (p == NULL)     
  7.     {  cout < <“allocte failed” < <endl;  exit( -1 );    }     
  8.     // ...     
  9.     long * q = new(p)long(1000);     
  10.     delete [ ]p;    //只释放 p,不要用q释放。     
  11. }   
 p和q仅仅是首址相同,所构建的对象可以类型不同。所“放置”的空间应小于原空间,以防不测。当”放置new”超过了申请的范围,Debug版下会挂机,但Release版竟然能运行而不出错!

该运算符的作用是:只要第一次分配成功,不再担心分配失败。

提示3:placement new 的主要用途:反复使用一块较大的动态分配成功的内存来构造不同类型的对象或者他们的数组。这样可以避免申请失败的徒劳,又可以避免使用后的释放。

[cpp]  view plain copy
  1. # include <new>     
  2. # include <iostream>     
  3. void main()     
  4. {  using namespace std;     
  5.     char * p = new(nothrowchar [100];     
  6.     if (p == NULL)     
  7.     {  cout < <“allocte failed” < <endl;  exit( -1 );    }     
  8.     long * q1 = new(p)long(100);     
  9.     // 使用q1  ...     
  10.     int * q2 = new(p) int[100/sizeof(int) ];     
  11.     // 使用q2 ...     
  12.     ADT * q3 = new(p) ADT[100/sizeof(ADT) ];     
  13.     // 使用q3  然后释放对象 ...     
  14.     delete [ ]p;    //只释放空间,不再析构对象。     
  15. }  
注意:使用该运算符构造的对象或数组,一定要显式调用析构函数不可用delete代替析构,因为placement new 的对象的大小不再与原空间相同。因此使用delete会造成内存泄露,或者在之后释放内存时出现运行时错误。
[cpp]  view plain copy
  1. # include <new>     
  2. # include <iostream>     
  3. void main()     
  4. {  using namespace std;     
  5.     char * p = new(nothrowchar [sizeof(ADT)+2];     
  6.     if (p == NULL)     
  7.     {  cout < <“allocte failed” < <endl;  exit( -1 );    }     
  8.     // ...     
  9.     ADT * q = new(p) ADT;     
  10.     // ...     
  11.     // delete q;    // 错误     
  12.     q-> ADT::~ADT(); //显式调用析构函数,仅释放对象     
  13.     delete [ ]p;    //最后,再用原指针来释放内存.     
  14. }   
 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值