• [C++] 重载new和delete——控制内存分配


     
    1、new和delete表达式的工作机理
        
    1)new表达式实际执行了三步
    string *sp=new string("aaaa");
    string *arr=new string[10];//string采用默认初始化
         a、调用一个名为operator new(或者operator new[])的标准库函数,分配一块足够大的、原始的、未命名的内存空间,来准备存储对象或者对象的数组;
         b、编译器运行相应的构造函数构造这些对象,在这里运行的是string的构造函数;
         c、返回一个指向该对象或者对象数组的指针。
     
    2)delete执行了两步操作:
    delete sp;
    delete []arr;
          a、对sp或者arr所指的数组中的元素执行相应的析构函数;
          b、编译器调用名为operator delete或者operator delete[]的标准库函数释放内存空间。
     
    所以,想要控制内存分配,需要重载标准库函数中的operator new和operator delete函数,可以在类中重载,也可以在类外(全局)重载;使用作用域运算符::可以忽略类中的函数,直接执行全局作用域中的版本,::operator new,::operator delete。
     
    2、标准库函数中的operator new 和operator delete
    #ifndef _NEWANDDELETE_H_
    #define _NEWANDDELETE_H_
    #include<new>
    #include<cstdlib>
    using namespace std;
    
    class NewAndDelete {
    public:
        /**
        * 以下是标准库函数中的operate new和operator delete
        * 前面4个会抛出异常,后面4个不会抛出异常
        * 这几个运算符函数是隐式静态的,因为operator new在构造对象之前,用来分配空间;operator delete在对象销毁之后,用来释放空间
        * operator new 或者operator new[]的返回类型必须是void*,第一个形参类型必须是size_t并且没有默认实参,size_t代表要分配的空间的大小
        * operator delete或者operator delete[]返回类型必须是void,第一个形参类型必须是void*,用指向待释放内存的指针来初始化
        * 这两个函数的行为与allocator类中allocate()和deallocate()很类似
        */
        static void *operator new(size_t);
        static void *operator new[](size_t);
        static void operator delete(void*)noexcept;
        static void operator delete[](void*)noexcept;
    
        static void *operator new(size_t, nothrow_t&)noexcept;
        static void *operator new(size_t, nothrow_t&)noexcept;
        static void operator delete(void*, nothrow_t&)noexcept;
        static void operator delete[](void*, nothrow_t&)noexcept;
    };
    
    //实现示例——使用malloc和free
    void* NewAndDelete::operator new(size_t size) {
        if (void *mem = malloc(size))
            return mem;
        else
            throw bad_alloc();//抛出异常
    }
    void NewAndDelete::operator delete(void *mem)noexcept {
        free(mem);
    }
    void* NewAndDelete::operator new(size_t size, nothrow_t& no)noexcept {//不抛出异常,返回空指针
        void *p;
        if (void *mem = malloc(size))
            return mem;
        else return p;
    }
    void NewAndDelete::operator delete(void *mem, nothrow_t& no)noexcept {
        free(mem);
    }
    #endif
  • 相关阅读:
    第二次作业
    第一次作业
    第三次作业
    第二次作业
    第一次作业
    第五次作业
    第四次作业
    第三次作业
    第二次作业
    第一次作业
  • 原文地址:https://www.cnblogs.com/zhizhiyu/p/10162180.html
Copyright © 2020-2023  润新知