zoukankan      html  css  js  c++  java
  • C++进阶--解谜operator new/delete

    //############################################################################
    // 解谜operator new/delete
    
    /* 执行下面代码会发生什么? 
     */
    
       dog* pd = new dog();
    /* 
     * Step 1. 调用operator new分配内存
     * Step 2. 调用构造函数构造dog
     * Step 3. 如果第2部抛异常,调用operator delete释放第1步分配的内存 
     */
       delete pd;
    /* 
     * Step 1. 调用dog的析构函数
     * Step 2. 调用operator delete释放内存
     */
    
    
    /*
     * 自己实现operator new:
     *
     * 注意: new handler是当operator new分配内存失败时调用的函数
     *   set_new_handler()函数设置一个新的new handler并且返回当前的new handler
     */
    void* operator new(std::size_t size) throw(std::bad_alloc) {
       while (true) {
          void* pMem = malloc(size);   // 分配内存
          if (pMem) 
             return pMem;              // 成功则返回指针
    
          std::new_handler Handler = std::set_new_handler(0);  // 获取当前的new handler
          std::set_new_handler(Handler);  //写回
    
          if (Handler)
             (*Handler)();            // 调用new handler
          else
             throw bad_alloc();       // 如果new handler为空, 抛异常
       }
    }
    
    
    /* 
     * 成员函数中的Operator new
     */
    class dog {
       ...
       public:
       static void* operator new(std::size_t size) throw(std::bad_alloc) 
       {
    //      if (size == sizeof(dog))
             customNewForDog(size);
     //     else
    //         ::operator new(size);
       }
       ...
    };
    
    class yellowdog : public dog {
       int age;
       static void* operator new(std::size_t size) throw(std::bad_alloc) 
    };
    
    int main() {
       yellowdog* py= new yellowdog();   //调用了dog的operator new
    }
    
    /*
    * 解决方法 1:
    *     if (size == sizeof(dog))  //加判断
    *        customNewForDog();
    *     else
    *        return ::operator new(size);
    *
    * 解决方法 2:
    *     yellowdog也重载operator new
    */
    
    
    
    /* operator delete也是类似 */
    class dog {
       static void operator delete(void* pMemory) throw() {  //
          cout << "Bo is deleting a dog, 
    ";
          customDeleteForDog();
          free(pMemory);
       }
    //   virtual ~dog() {};   
    };
    
    class yellowdog : public dog {
       static void operator delete(void* pMemory) throw() {
          cout << "Bo is deleting a yellowdog, 
    ";
          customDeleteForYellowDog();
          free(pMemory);
       }
    };
    
    int main() {
       dog* pd = new yellowdog();
       delete pd;   //调用了dog的operator delete
    }
    
    // 如何解决?
    // operator delete定义成虚函数?
    // 不行!不能既是静态函数(对象无关)又是虚函数(对象相关)
    //
    //
    // 解决方法:
    //   virtual ~dog() {}
    // 为什么加个虚析构函数就ok?
    // 先调析构(多态),再释放内存
    
    
    
    
    
    /*
     * 为什么要自定义new/delete
     *
     * 1. 使用错误检测: 
     *    - 内存泄漏检测/垃圾回收. 
     *    - 数组的索引超出范围,在内存的首尾做签名,就可以检测数组越界
     * 2. 提升效率:
     *    a. 将相关对象聚类,减少页错误(不命中)
     *    b. 固定大小分配(适合很多小对象的应用)
     *    c. 将相似尺寸的对象排到同一位置以减小碎片
     * 3. 执行额外的任务:
     *    a. 将去分配的内存清0--安全性.
     *    b. 收集使用统计
     */
    
    /*
     * 写一个好的内存管理器很难!
     *
     * 在写自己版本的之前, 考虑:
     *
     * 1. 根据你的需要调教下你的编译器;
     * 2. 搜索内存管理库, 例如boost中的pool库
     */
    
  • 相关阅读:
    ZROI 19.08.04模拟赛
    具体数学 第一章 递归问题
    ZROI 19.08.02 杂题选讲
    win下在虚拟机安装CentOS 7 Linux系统
    ICP算法(迭代最近点)
    Python学习笔记(一)
    堆和堆排序
    笔试面试题记录-
    笔试面试记录-字符串转换成整型数等(aatoi,itoa)
    支持向量机原理(一) 线性支持向量机
  • 原文地址:https://www.cnblogs.com/logchen/p/10182396.html
Copyright © 2011-2022 走看看