码迷,mamicode.com
首页 > 编程语言 > 详细

Effective C++ 条款52

时间:2015-06-17 11:40:59      阅读:136      评论:0      收藏:0      [点我收藏+]

标签:placement   内存   

写了placement new也要写placement delete

本文主要内容是对placement new 和 placement delete的介绍,以及在什么情况下使用placement new和placement delete。

对于语句Widget* pw=new Widget;来说,该语句做了两件事情,第一件事情是申请了内存区域;第二件事情是在该内存区上进行对象的构造,即调用构造函数。我们设想其中一种执行情况,当第一件事情完成,而第二件事情出现异常,那么我们应该怎么去处理,很显然我们需要将这部分内存还原回去,于是如何还原回去成了我们需要解决的问题。
这个时候,客户没有能力去归还内存,因为如果Widget构造函数抛出异常,那么pw尚未被赋值,客户手中的指针还没有指向开辟的内存。释放内存的任务落到了C++运行期系统身上。

 class Widget{
    public:
        static void* operator new(std::size_t size, std::ostream& logStream)//非正常形式的new
            throw(std::bad_alloc);
        static void operator delete(void* pMemory, std::size_t size)//正常的class专属delete
            throw();
        ……
    };
Widget* pw = new(std::cerr) Widget;

我们看到上面的代码,当调用new(std::cerr) Widget语句时,我们就进入了Widget的自定义new函数中,当构造函数中出现异常的时候,我们可以在构造函数中调用对应的delete函数,实现内存回收。大家如果得到签名式,回收内存就简单了。

我们先来介绍一下placement new 和 placement delete的介绍,术语placement new意味着带有额外参数的new,如void* operator new(std::size_t, void* pMemory) throw();,placement delete味着带有额外参数的delete。

解决问题的关键变成了如何得到合适的 delete。
根据作者的说明,我们知道
placement delete只有在“伴随placement new调用而触发的构造函数”出现异常时才会被调用。对一个指针施行delete绝不会导致调用placement delete。
这意味对所有placement new我们必须同时提供一个正常的delete和一个placement版本。

class Derived: public Base{
    public:
        ……
        static void* operator new(std::size_t size) throw(std::bad_alloc);//重新声明正常形式的new
    };
    Derived* pd=new (std::clog) Derived;//错误,因为Base的placement new被掩盖了
    Derived* pd1=new Derived;//正确
在缺省情况下,C++在global作用域内提供以下形式的operator newvoid* operator(std::size_t) throw(std::bad_alloc);//normal new
    void* operator(std::size_t, void*) throw();//placement new
    void* operator(std::size_t, const std::nothrow_t&) throw();//nothrow new


class StadardNewDeleteForms{
    public:
        //normal
        static void* operator new(std::size_t size) throw(std::bad_alloc)
        {return ::operator new(size);}
        static void operator delete(void* pMemory) throw()
        {::operator delete(pMemory);}
        //placement
        static void* operator new(std::size_t size, void* ptr) throw(std::bad_alloc)
        {return ::operator new(size, ptr);}
        static void operator delete(void* pMemory, void* ptr) throw()
        {::operator delete(pMemory, ptr);}
        //nothrow
        static void* operator new(std::size_t size, const std::nothrow_t& nt) throw(std::bad_alloc)
        {return ::operator new(size,nt);}
        static void operator delete(void* pMemory,const std::nothrow_t&) throw()
        {::operator delete(pMemory);}
    };

class Widget: public StandardNewDeleteForms{
    public:
        //让这些形式可见
        using StandardNewDeleteForms::operator new;
        using StandardNewDeleteForms::operator delete;
        //添加自己定义的
        static void* operator new(std::size_t size, std::ostream& logStream) throw(std:;bad_alloc);
        static void operator detele(std::size_t size, std::ostream& logStream) throw();
    };

Effective C++ 条款52

标签:placement   内存   

原文地址:http://blog.csdn.net/u011058765/article/details/46530259

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!