C++之编写new和delete时需要固守常规(51)---《Effective C++》
2017-08-15 21:28
661 查看
条款51:编写new和delete时需固守常规
operator new中包含一个无限循环,而上述伪码明白表达出这个循环;“while(true)”就是那个无限循环,退出循环的唯一方法是:内存被成功分配或者new_hanlder从条款49的多个选择中选出一种进行选择,选择包括:让更多内存可用、安装另一个new_handler、卸载new_handler、抛出bad_alloc异常或者承认失败或者直接return,下面我们来看看operator new的伪码:void* operator new(std::size_t size) throw(std::bad_alloc){ using namespace std; if(size==0){ size=1; } while(true){ 尝试分配size bytes; if(分配成功) return (一个指针,指向分配得来的内存); //分配失败 new_handler globalHandler=set_new_handler(0); set_new_handler(globalHandler); if(globalHandler) (*globalHandler)(); else throw std::bad_alloc(); } }
还有一个问题,许多人并没有意识到operator new成员函数会被derived classes继承,这回导致很多复杂的问题。因此我们需要重载机制,即将operator new和operator delete函数声明为virtual函数。
class Base{ public: static void* operator new(std::size_t size) throw(std::bad_alloc); ... }; void Base::operator new(std::size_t size) throw(std::bad_alloc){ if(size!=sizeof(Base)) return ::operator new(size);//如果大小错误,令标准的operator new起而处理 ...//否则在这里进行处理 class Derived:public Base {...}; Derived *p=new Derived;//这里调用的是Base::operator new
上述代码我们可以看到operator new成员函数会被继承,产生一些问题;同时我们在自定义operator new函数时候需要考虑生成失败的情况。
针对operator delete函数,只需要记住的唯一事情就是C++保证“删除null指针永远安全”,所以必须兑现这项承诺。
void operator delete(void* rawMemory) throw(){ if(rawMemory==0) return;//如果被删除的是个null指针,那就什么也不用做 现在,归还rawMemory所指的内存; }
下面,我们写一个较为健全的程序,定义operator new和operator delete。
class Base{ public: static void* operator new(std::size_t size) throw(std::bad_alloc); static void operator delete(void* rawMemory,std::size_t size) throw(); ... }; void Base::operator delete(void* rawMeomory,std::size_t size) throw(){ if(rawMemory==0) return; if(size!=sizeof(Base)){ ::operator delete(rawMemory); return; } 现在,归还rawMemory所指的内存; return; }
总结:
1)operator new应该内含一个 无穷循环,并在其中尝试分配内存,如果它无法满足内存需求,就该调用new_handler。它也有能力处理0bytes申请,Cass专属版本则还应该处理“比正确大小更大(错误)的申请”;
2)operator delete应该在收到null指针时不做任何事,Class专属版本还应该处理“比正确大小更大的(错误)申请”。
相关文章推荐
- 《Effective C++》:条款51:编写new和delete时需固守常规
- Effective C++ 条款 51:编写new和delete时需固守常规
- effective C++ 条款 51:编写new和delete时需固守常规
- 条款51:编写new以及delete的时候需要固守常规
- Effective C++ -----条款51:编写new 和delete 时需固守常规
- Effective C++ 条款51 编写new和delete时需固守常规
- effective C++ 条款 51:编写new和delete时需固守常规
- Effective C++ 3e----new & delete(八)条款51:编写new和delete时需固守常规
- 条款51:编写new和delete时需固守常规(Adhere to convention when writing new and delete.)
- 【51】编写new和delete时需固守常规
- 条款51:编写new和delete时需固守常规
- 《Effective C++》读书笔记之item51:编写new和delete时需固守常规
- 条款51:编写new和delete时需固守常规
- 条款51:编写new和delete时需固守常规
- 条款51:编写new和delete需固守常规
- 编写new和delete时需固守常规
- 读书笔记 effective c++ Item 51 实现new和delete的时候要遵守约定
- 面试题:C++有了malloc/free,为什么还需要new、delete?
- C++中有了malloc/free,为什么还需要new/delete
- C++有了malloc和free,为什么还需要new/delete