胸围80是多大:C++中运算符New的三种使用方式

来源:百度文库 编辑:九乡新闻网 时间:2024/05/21 15:46:40

这是在林锐的《高质量程序设计指南》中看到的,特此记录下。

1. plain new 普通new

Cpp代码
  1. void*operator new(std::size_t)throw(std::bad_alloc);   
  2. void operator delete( void *) throw();   
  3.   
void*operator new(std::size_t)throw(std::bad_alloc);void operator delete( void *) throw();

  该运算符在分配失败时将抛出异常,而非返回NULL。使用时要包含 头文件。正常使用new,但要配以异常处理。如:

Cpp代码
  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 < 
  12. }   
char *getMemory(unsigned long size){    char * p = new char[size];return p; }void main(void ){    try{char * p = getMemory(1000000);//可能发生异常// ...delete [ ] p;}catch(const std::bad_alloc & ex){  cout < 

 

 

2.nothrow new  不抛掷异常new

Cpp代码
  1. void*operator new(std::size_t,const std::nothrow_t & )throw();   
  2. void operator delete( void *) throw();   
void*operator new(std::size_t,const std::nothrow_t & )throw();void operator delete( void *) throw(); 

 该运算符在分配失败时不抛出异常,而是返回NULL。使用时要包含 头文件。
该函数的第2形参是 struct nothrow_t {  };它是个全局常对象 const nothrow_t nothrow; 用来作为 new 运算符的标志,以区别前一个new.

Cpp代码
  1. void func(unsinged long length)   
  2. {   
  3.        unsinged char * p = new(nothrow) unsinged char[length];   
  4.       //在使用这种new时要加(nothrow) ,明示不使用异常处理 。   
  5.   
  6.     if ( p == NULL)  // 因不抛异常,故定要检查   
  7.         cout < <“allocte failed !”;   
  8.       // ...   
  9.      delete [ ] p;   
  10. }   
void func(unsinged long length){unsinged char * p = new(nothrow) unsinged char[length];//在使用这种new时要加(nothrow) ,明示不使用异常处理 。if ( p == NULL)  // 因不抛异常,故定要检查cout < <“allocte failed !”;// ...delete [ ] p;} 

 

 

3.placement new 放置new

Cpp代码
  1. void*operator new(std::size_t ,void *);   
  2. void operator delete( void * ,void *);   
void*operator new(std::size_t ,void *);void operator delete( void * ,void *); 

 该运算符是在已分配的内存上重新构造对象,因为不分配内存,所以不必担心分配失败。唯一的工作是调用构造函数。要包含 头文件。

Cpp代码
  1. # include    
  2. # include    
  3. void main()   
  4. {  using namespace std;   
  5.     char * p = new(nothrow) char [4];   
  6.     if (p == NULL)   
  7.     {  cout < <“allocte failed” < 
  8.     // ...   
  9.     long * q = new(p)long(1000);   
  10.     delete [ ]p;    //只释放 p,不要用q释放。   
  11. }   
# include # include void main(){  using namespace std;char * p = new(nothrow) char [4];if (p == NULL){  cout < <“allocte failed” < 

 p和q仅仅是首址相同,所构建的对象可以类型不同。所“放置”的空间应小于原空间,以防不测。当”放置new”超过了申请的范围,Debug版下会挂机,但Release版竟然能运行而不出错!

 

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

Cpp代码
  1. # include    
  2. # include    
  3. void main()   
  4. {  using namespace std;   
  5.     char * p = new(nothrow) char [100];   
  6.     if (p == NULL)   
  7.     {  cout < <“allocte failed” < 
  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. }   
# include # include void main(){  using namespace std;char * p = new(nothrow) char [100];if (p == NULL){  cout < <“allocte failed” < 

 注意:使用该运算符构造的对象或数组,一定要显式调用析构函数,不可用delete代替析构,因为placement new 的对象的大小不再与原空间相同。

Cpp代码
  1. # include    
  2. # include    
  3. void main()   
  4. {  using namespace std;   
  5.     char * p = new(nothrow) char [sizeof(ADT)+2];   
  6.     if (p == NULL)   
  7.     {  cout < <“allocte failed” < 
  8.     // ...   
  9.     ADT * q = new(p) ADT;   
  10.     // ...   
  11.     // delete q;    // 错误   
  12.     q-> ADT::~ADT(); //显式调用析构函数,仅释放对象   
  13.     delete [ ]p;    //最后,再用原指针来释放内存.   
  14. }   
# include # include void main(){  using namespace std;char * p = new(nothrow) char [sizeof(ADT)+2];if (p == NULL){  cout < <“allocte failed” <  ADT::~ADT(); //显式调用析构函数,仅释放对象delete [ ]p;    //最后,再用原指针来释放内存.} 

  placement new 的主要用途就是可以反复使用一块已申请成功的内存空间。这样可以避免申请失败的徒劳,又可以避免使用后的释放。

    特别要注意的是对于 placement new 绝不可以调用的delete, 因为该new只是使用别人替它申请的地方(只是个租房户,不是房主。无权将房子卖掉)。释放内存是nothrow new的事,即要使用原来的指针释放内存.