Effective C++ 读书笔记(八)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_40028201/article/details/89673305

Effective C++ 读书笔记(八)

8、定制new和delete

条款 49 :了解new-handler的行为

  1. set_new_handler允许客户指定一个函数,在内存分配无法获得满足时被调用。
  2. nothrow new是一个颇为局限的工具,因为它只适用于内存分配;后继的构造函数调用还是有可能抛出异常。

条款 51:编写new和delete时需固守常规

  1. operator new应该内涵死循环,并在其中尝试分配内存,如果它无法满足内存需求,就该调用new-handler。它也应该有能力处理0bytes申请。class专属版本的还应该处理“比正确大小更大的(错误)申请”。

    //非成员函数
    void* operator new(std::size_t size) throw(std::bad_alloc)
    {
        using namespace std;
        if(size==0){//处理0-byte申请
            size=1;
        }
        while(true){
            尝试分配size bytes;
            if(分配成功)
                return 指向分配得来的内存;
            //分配失败,找到当前的new-handling函数
            new_handler globalHandler=set_new_handler(0);
            set_new_handler(globalHandler);
    
            if(globalHandler) (*globalHandler)();
            else throw std::bad_alloc();
        }
    }
    //成员函数
    class Base{
    public:
        static void* operator new(std::size_t size) throw(std::bad_alloc)
        ……
    };
    class Derived:public Base
    {……};//假设为重新定义operator new
    Derived* p=new Derived;//这里调用了Base::operator new
    
    如果是class专属的operator new,应该改为这样:
    
    void* Base::operator new(std::size_t size) throw(std::bad_alloc)
    {
        if(size!=sizeof(Base))
            return ::operator new(size);//使用标准的operator new
        ……
    }
    
    
  2. operator delete应该在收到指针时不做任何事。class专属版本则还应该处理“比正确大小更大的(错误)申请”。

    //非成员函数
    void operator delete(void* rawMemory) throw()
    {
        if(rawMemory==0) return;
    
        归还rawMemory所指内存;
    }
    //成员函数
    void Base::operator delete(void rawMemory, std::size_t size) throw()
    {
        if(rawMemory==0) return;
        if(size!=sizeof(Base)){
            ::operator delete(rawMemory);
            return ;
        }
        归还rawMemory所指内存;
        return ;
    }
    

条款52 写了placement new也要写placement delete

  1. 当编写一个placement operator new时,也要编写对应版本的placement operator delete。否则就可能造成隐蔽的内存泄露
  2. 当声明了placement new和placement delete时,就会掩盖正常版本。

9、杂项讨论

条款53: 不要忽视编译器的警告

  1. 请严肃对待编译器的警告,努力在编译器最高警告级别下争取 “无警告”。

条款54 : 让自己熟悉包括 TR1 在内的标准程序库

  1. C++ 标准程序库主要由 STL,iostream,locales 组成,并包含 C99 标准程序库。
  2. TR1 组件都在 std::tr1:: 命名空间下,以下是组件实例:
    1. 智能指针。
    2. tr1::function,常用于实现回调函数。
    3. tr1::bind,能够做 STL 绑定器 bind1st 和 bind2nd 所做的每一件事,而又更多。
    4. Hash tables,用来实现 sets,multisets,maps 和 multi-maps。
    5. 正则表达式。
    6. Tuples 变量组,这是标准程序库 pair 的升级,pair 只能持有两个对象,而 tr1::tuple 可持有任意个数对象。
    7. tr1::array,本质是个 STL 化的数组,即一个支持成员函数 begin 和 end 的数组。不过它大小固定,并不使用动态内存。
    8. tr1::mem_fn,这是一个语句上构造与成员函数指针(member function pointers)一致的东西。同样容纳并扩充了 C++98 的 mem_fun 和 mem_fun_ref 的能力。
    9. tr1::reference_wrapper,一个让引用的行为更像对象的设施。
    10. 随机数生成工具,它大大超越了 rand。
    11. 数学特殊函数,包括 Laguerre 多项式、Bessel 函数、完全椭圆积分,以及更多数学函数。
    12. C99 兼容扩充,这是一大堆函数和模版用来将许多新的 C99 程序库特性带入 C++。
    13. Type traits,一组 traits classes(条款 47),用以提供类型的编译期信息。
    14. tr1::result_of,这是一个用来推导函数调用的返回值类型的模版。

条款55: 让自己熟悉Boost

  1. Boost 是一个社群,也是一个网站。致力于免费、源码开放、同僚复审的 C++ 程序库开发。

  2. Boost 提供许多 TR1 组件的实现品,以及其它许多程序库

猜你喜欢

转载自blog.csdn.net/qq_40028201/article/details/89673305