1,问题:
1,new 关键字创建出来的对象位于什么地方?
1,位于堆空间;
2,有没有可能位于其它地方?
1,有;
2,通过一些方式可以使动态创建的对象位于静态存储区;
3,这个存储区在程序结束后释放;
2,new/delete 被忽略的事实:
1,new/delete 的本质是 C++ 预定义的操作符;
1,new/delete 是关键字,但本质是预定义的操作符;
2,C++ 中操作符可以重载;
2,C++ 对这两个操作符做了严格的行为定义;
1,new:
1,获取足够大的内存空间(默认为堆空间);
2,在获取的空间中调用构造函数创建对象;
2,delete:
1,调用析构函数销毁对象;
2,归还对象所占用的空间(默认为堆空间);
3,在 C++ 中能够重载 new/delete 操作符:
1,全局重载(不推荐);
1,实际工程开发中不建议这样做
2,局部重载(针对具体类型进行重载);
1,针对具体的类重载;
3,重载 new/delete 的意义在于改变动态对象创建时的内存分配方式;
1,可以将创建的对象放到其它的内存空间里面去;
4,new/delete 的重载方式:
1,代码示例:
1 // static member function 2 void* operator new(unsinged int size) // 第一步获取内存,参数表示需要获取的内存大小; 3 { 4 void* ret = NULL; 5 6 /* ret point to allocated memory */ // 第二步在内存中调用构造函数创建对象; 7 8 return ret; 9 } 10 11 // static member function 12 void operator delete (void* p) // p 指针指向对应的对象地址,也就是要释放的地址; 13 { 14 /* free the memory which is pointed by p */ 15 }
2,通过函数来对这两个操作符进行重载;
3,一般针对具体类来重载,所以说 new/delete 的重载函数就是类的成员函数,并且这两个重载函数默认为静态成员函数,写不写 static 都是静态成员函数;
3,静态存储区中创建动态对象编程实验:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 class Test 7 { 8 static const unsigned int COUNT = 4; 9 10 static char c_buffer[]; // 本质是这里申请空间而下面只是标记使用而已; 11 static char c_map[]; 12 13 int m_value; 14 public: 15 void* operator new (unsigned int size) 16 { 17 void* ret = NULL; // 如果这片内存已经满了,返回空; 18 19 /* 查找在 c_buffer 里面那些位置是空闲的,可以用来创建 Test 对象 */ 20 for(int i=0; i<COUNT; i++) 21 { 22 if( !c_map[i] ) // 当前空间不可用了; 23 { 24 c_map[i] = 1; // 标记为不可用; 25 26 ret = c_buffer + i * sizeof(Test); // 查找 c_buffer 这片可用内存空间的首地址,并返回这片空间; 27 28 cout << "succeed to allocate memory: " << ret << endl; 29 30 break; 31 } 32 } 33 34 return ret; 35 } 36 37 void operator delete (void* p) 38 { 39 if( p != NULL ) // 空指针时候什么都不处理; 40 { 41 char* mem = reinterpret_cast<char*>(p); 42 int index = (mem - c_buffer) / sizeof(Test); // 得到要释放的动态对象在 c_map 中的位置; 43 int flag = (mem - c_buffer) % sizeof(Test); // 这些位置必须是固定的,如果 flag 不为 0,指针则不合法; 44 45 if( (flag == 0) && (0 <= index) && (index < COUNT) ) 46 { 47 c_map[index] = 0; /