欢迎来到天天文库
浏览记录
ID:15565727
大小:41.50 KB
页数:6页
时间:2018-08-04
《c++关键字new学习》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、C++关键字new学习很多新手对C++关键字new可能不是很了解吧,今天我一起来学习一下。 “new”是C++的一个关键字,同时也是操作符。关于new的话题非常多,因为它确实比较复杂,也非常神秘,下面我将把我了解到的与new有关的内容做一个总结。new的过程classA{ inti;public: A(int_i):i(_i*_i){} voidSay() {printf("i=%d\",i);}};//调用new:A*pa=newA(3);A*pa=(A*)malloc(sizeof(A));pa->A::A(3);returnpa;到目前
2、为止,本文所提到的new都是指的“newoperator”或称为“newexpression”,但事实上在C++中一提到new,至少可能代表以下三种含义:newoperator、operatornew、placementnew。newoperator的第一步分配内存实际上是通过调用operatornew来完成的,这里的new实际上是像加减乘除一样的操作符,因此也是可以重载的。operatornew默认情况下首先调用分配内存的代码,尝试得到一段堆上的空间,如果成功就返回,如果失败,则转而去调用一个new_hander,然后继续重复前面过程。如果我们对这个过程不满
3、意,就可以重载operatornew,来设置我们希望的行为。例如:这里通过::operatornew调用了原有的全局的new,实现了在分配内存之前输出一句话。全局的operatornew也是可以重载的,但这样一来就不能再递归的使用new来分配内存,而只能使用malloc了:相应的,delete也有deleteoperator和operatordelete之分,后者也是可以重载的。并且,如果重载了operatornew,就应该也相应的重载operatordelete,这是良好的编程习惯。#includevoidmain(){ chars[size
4、of(A)]; A*p=(A*)s; new(p)A(3);//p->A::A(3); p->Say();}p->~A();正如前面所说,operatornew的默认行为是请求分配内存,如果成功则返回此内存地址,如果失败则调用一个new_handler,然后再重复此过程。于是,想要从operatornew的执行过程中返回,则必然需要满足下列条件之一:分配内存成功 new_handler中抛出bad_alloc异常 new_handler中调用exit()或类似的函数,使程序结束void*operatornew(size_tsi
5、ze){ void*p=null while(!(p=malloc(size))) { if(null==new_handler) throwbad_alloc(); try { new_handler(); } catch(bad_alloce) { throwe; } catch(…) {} } returnp;}voidMyNewHandler(){ printf(“Newhandlercalled!
6、”); throwstd::bad_alloc();}std::set_new_handler(MyNewHandler);在编程时我们应该注意到对new的调用是有可能有异常被抛出的,因此在new的代码周围应该注意保持其事务性,即不能因为调用new失败抛出异常来导致不正确的程序逻辑或数据结构的出现。例如:静态变量count用于记录此类型生成的实例的个数,在上述代码中,如果因new分配内存失败而抛出异常,那么其实例个数并没有增加,但count变量的值却已经多了一个,从而数据结构被破坏。正确的写法是:这样一来,如果new失败则直接抛出异常,count的值不会增加
7、。类似的,在处理线程同步时,也要注意类似的问题:此时,如果new失败,unlock将不会被执行,于是不仅造成了一个指向不正确地址的指针p的存在,还将导致someMutex永远不会被解锁。这种情况是要注意避免的。(参考:C++箴言:争取异常安全的代码)STL的内存分配与traits技巧为了实现这种方式,STL使用了placementnew,通过在自己管理的内存空间上使用placementnew来构造对象,以达到原有newoperator所具有的功能。此函数接收一个已构造的对象,通过拷贝构造的方式在给定的内存地址p上构造一个新对象,代码中后半截T1(value)便
8、是placementnew语法中调用构
此文档下载收益归作者所有