这是在林锐的《高质量程序设计指南》中看到的,特此记录下。
1. plain new 普通new
void*operator new(std::size_t)throw(std::bad_alloc);
void operator delete( void *) throw();
该运算符在分配失败时将抛出异常,而非返回NULL。使用时要包含 <new>头文件。正常使用new,但要配以异常处理。如:
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 < <ex.what(); }
}
2.nothrow new 不抛掷异常new
void*operator new(std::size_t,const std::nothrow_t & )throw();
void operator delete( void *) throw();
该运算符在分配失败时不抛出异常,而是返回NULL。使用时要包含 <new>头文件。
该函数的第2形参是 struct nothrow_t { };它是个全局常对象 const nothrow_t nothrow; 用来作为 new 运算符的标志,以区别前一个new.
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
void*operator new(std::size_t ,void *);
void operator delete( void * ,void *);
该运算符是在已分配的内存上重新构造对象,因为不分配内存,所以不必担心分配失败。唯一的工作是调用构造函数。要包含 <new>头文件。
# include <new>
# include <iostream>
void main()
{ using namespace std;
char * p = new(nothrow) char [4];
if (p == NULL)
{ cout < <“allocte failed” < <endl; exit( -1 ); }
// ...
long * q = new(p)long(1000);
delete [ ]p; //只释放 p,不要用q释放。
}
p和q仅仅是首址相同,所构建的对象可以类型不同。所“放置”的空间应小于原空间,以防不测。当”放置new”超过了申请的范围,Debug版下会挂机,但Release版竟然能运行而不出错!
该运算符的作用是:只要第一次分配成功,不再担心分配失败。
# include <new>
# include <iostream>
void main()
{ using namespace std;
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; //只释放空间,不再析构对象。
}
注意:使用该运算符构造的对象或数组,一定要显式调用析构函数,不可用delete代替析构,因为placement new 的对象的大小不再与原空间相同。
# include <new>
# include <iostream>
void main()
{ using namespace std;
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的事,即要使用原来的指针释放内存.
分享到:
相关推荐
这是一个精讲c++运算符重载的好东西,是我认真收集和整理的,自我认为这是一个很好的东西。希望大家喜欢!
JavaScript中运算符使用及例子
今天小编就为大家分享一篇关于C++中运算符重载的规则语法实例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
主要介绍了C/C++中运算符的优先级、运算符的结合性详解的相关资料,需要的朋友可以参考下
主要介绍了C++中运算符 &和&&、|和|| 的详解及区别的相关资料,这里举例说明该如何区别他们的不同,需要的朋友可以参考下
Java中运算符的优先级共2页.pdf.zip
Java中运算符的优先级.pdf 学习资料 复习资料 教学资源
主要介绍了讲解Python中运算符使用时的优先级,是Python学习当中的基础知识,需要的朋友可以参考下
详细介绍了C++中运算符的重载,使读者深入理解C++中运算符的重载的方法
c++运算符的优先级和结合性,doc文档,表格排版
python中运算符+的⽤法_Python中的运算符⽤法全解 就像数学中⼀样, Python之类的编程语⾔也具有运算符。你可以将它们视为基于计算机科学的极其简单的功能。这些是可以简化计算机程序 的最简单的操作。对于任何有抱负...
c中有多个运算符,这是所有运算符的优先级排列,为进一步学习c开发做好准备。
言简意赅说明java中的运算符的优先级,便于理解。
我们首先表明,一类算子在⊗AℋB上作用于给定的二分纯态时,可以在保持其映射的同时将其在ℋA⊗B上的支持范围缩小到ℋA或ℋB。 利用这个结果,我们展示了如何系统地构造针对纠删误差的量子纠错码的解码器。...
在讲is和==这两种运算符区别之前,首先要知道Python中对象包含的三个基本要素,分别是:id(身份标识)、python type()(数据类型)和value(值)。is和==都是对对象进行比较判断作用的,但对对象比较判断的内容并不相同。...
C++中运算符的重载,++重载为前增量和后增量!!!!!
有关于C++中运算符重载的程序,有+ 、 += 、 = 、、 == 、 、 >> 等等