C++学习笔记--重载new和delete

来源:互联网 发布:西方人长相知乎 编辑:程序博客网 时间:2024/04/27 09:39

前面说过new申请的空间在堆空间上,那么我们能不能将new回来的空间存放在其他地方呢?能,那么该如何操作?

首先关注下new和delete的被忽略的东西:

new/delete本质上是C++预定义的操作符。

C++对这两个关键字做了严格的定义。new:获取足够大的空间,默认是堆空间上,使用new一个对象的空间时会调用构造函数;delete:会调用析构函数释放占用的空间,默认还是在堆空间,new和delete一定要成对使用避免出现bug。

由于C++是预定义的操作符所以被重载也是可以的,他们分为局部重载和全局重载,局部重载一般是在具体某个类里进行重载,不推荐使用全局重载,因为在全局重载后就会屏蔽系统自带的new,而局部重载在局部作用域范围之外将不会影响系统的new的使用。我们重载new和delete的意义在于改变动态对象创建时的内存分配方式。在进行重载之前值得提一下的是重载new和delete函数默认是静态成员函数,为什么设有这个规定呢,因为当没有对象存在时就无法动态的使用重载后的new出一个合法有效的对象出来。

在静态存储区中动态创建对象

class Test{private:    static const unsigned int COUNT;    static char c_buffer[];    static char c_map[];public:    void* operator new(unsigned int size)    {        void* ret = NULL;        for(int i = 0; i < COUNT; i++)        {             if( !c_map[i] )            {                c_map[i] = 1;                ret = c_buffer + i * sizeof(Test);                break;            }        }        return ret;    }   void operator delete(void *p)   {        if( p != NULL )        {            char* mem = reinterpret_cast<char*>(p);            int index = (mem - c_buffer) / sizeof(Test);//数组索引号            int flag = (mem - c_buffer) % sizeof(Test);//判断是否有效,当flag != 0表示地址无效            if( (flag == 0) && (0 <= index) && (index < COUNT) )            {                c_map[index] = 0;            }        }   }};const unsigned int Test:: COUNT = 4;char Test:: c_buffer[COUNT * sizeof(Test)] = {0};char Test:: c_map[COUNT] = {0};
首先定义一个静态的const常量,因为static只能访问static变量,标记类对象的个数,然后定义一个c_buffer作为类对象在静态存储区中的存储地址,c_buffer长度为COUNT个类对象的长度大小,c_map标记当前空间是否可用。

在new的重载中十分简单,只要找到一个可用的空间就退出并放回当前空间,要是一直找不到就返回NULL;delete的重载也很简单,只需将需要返回的空间标记为可用即可。

在指定位置创建对象