• 如何在指定的地址上创建C++对象


    如果已经掌握在静态存储区上创建对象的方法,那么可以扩展一下,可以在任意地址上创建C++对象。

    解决方案:
    -在类中重载new/delete操作符
    -在new的操作符重载函数中返回指定的地址
    -在delete操作符重载中标记对应的地址可用

    自定义动态对象的存储空间

    第二个实验指定了空间为静态存储区中的空间,现在扩展一下不指定具体的空间是哪里,可以临时的动态做决定。

    #include <iostream>
    #include <string>
    #include <cstdlib>
    
    using namespace std;
    
    class Test
    {
    private:
        static unsigned int c_count;
        static char* c_buffer;
        static char* c_map;
        int m_value;
    public:
        //动态指定想在什么样的内存空间中动态的创建对象
        static bool SetMemorySource(char* memory, unsigned int size)
        {
            bool ret = false;
            c_count = size / sizeof(Test); //需要保证设置进来的这片空间至少可以创建一个对象。
               ret = (c_count && (c_map =reinterpret_cast<char*>(calloc(c_count, sizeof(char)))));    //动态的创建一个标记数组
    
              if(ret) //当ret为true时,就可以确认这个空间设置是合法的,确实可以在指定的空间上创建对象了。
            {
                c_buffer = memory;
            }
            else
            {
                free(c_map);
    
                c_map = NULL;
                c_buffer = NULL;
                c_count = 0;
            }
    
            return ret;
        }
    
        void* operator new(unsigned int size)
        {
            void* ret = NULL;
    
            if(c_count > 0)
            {
                //利用for循环查找在c_buffer这片空间中哪些是空闲的,可以用于创建一个Test对象。
                //遍历c_count个位置,看每个位置有没有对象存在,如果没有对象存在,那么就可以返回这片内存空间。并且在这片内存空间中调用构造函数创建对象。
                  for(int i=0; i<c_count; i++)
                {
                    if(!c_map[i])
                    {
                        //表示当前的内存空间是可以用的
                              c_map[i] = 1;
                        ret = c_buffer + i * sizeof(Test);//做一个指针运算,用来查找c_buffer这块区域的可用空间的首地址
                              cout << "succeed to allocate memory: " << ret << endl;
    
                        break;
                    }
                }
            }
            else
            {
                ret = malloc(size);
            }
    
    
            return ret;
        }
    
        void operator delete(void* p)
        {
            if( p != NULL)
            {
                if(c_count > 0)
                {
                    char* mem = reinterpret_cast<char*>(p);
                    int index = (mem-c_buffer) / sizeof(Test);
                    int flag = (mem-c_buffer) % sizeof(Test);
    
                    if((flag == 0) && (0 <= index) && (index < c_count))
                    {
                        c_map[index] = 0;
                        cout << "succeed to free memory: " << p <<endl;
                    }
                }
                else
                {
                    free(p);
                }
    
            }
        }
    
    };
    
    unsigned int Test::c_count = 0;
    char* Test::c_buffer = NULL;
    char* Test::c_map = NULL;
    
    int main()
    {
       cout << "====== Test Single Object ======" << endl;
       Test* pt = new Test;
       delete pt;
    
       cout << "====== Test Object Array ======" << endl;
       Test* pa[5] = {0};
    
       for(int i=0; i<5; i++)
       {
            pa[i] = new Test;
            cout << "pa[" << i << "] = " << pa[i] << endl;
       }
    
       for(int i=0; i<5; i++)
       {
            cout << " delete" << pa[i] << endl;
            delete pa[i];
       }
    
        return 0;
    }

     为什么会出现上面的结果,因为我们在main函数中没有指定空间,因此new的时候,它走的是malloc,delete的时候,它走的是free.

    修改main函数如下:

    int main()
    {
       char buffer[12] = {0};
       Test::SetMemorySource(buffer,sizeof(buffer));
    
       cout << "====== Test Single Object ======" << endl;
       Test* pt = new Test;
       delete pt;
    
       cout << "====== Test Object Array ======" << endl;
       Test* pa[5] = {0};
    
       for(int i=0; i<5; i++)
       {
            pa[i] = new Test;
            cout << "pa[" << i << "] = " << pa[i] << endl;
       }
    
       for(int i=0; i<5; i++)
       {
            cout << " delete" << pa[i] << endl;
            delete pa[i];
       }
    
        return 0;
    }

  • 相关阅读:
    oracle 11g jdbc jar包在哪个文件目录
    Java生成验证码
    Oracle 安装“权限不够”
    Linux新建文件、文件夹
    基于Java web技术文件上传和下载功能开发实战练习视频(fileupload)
    springmvc的xml文件位置
    oracle 11g的OEM(企业管理器),https://主机ip:1158/em/console网页无法显示
    常见的开源协议分析
    约瑟夫问题猴子选大王
    TOJ1036.Rails STL栈
  • 原文地址:https://www.cnblogs.com/-glb/p/12296586.html
Copyright © 2020-2023  润新知