C++中的new和delete操作符重载
生活随笔
收集整理的這篇文章主要介紹了
C++中的new和delete操作符重载
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
文章目錄
- 1 new和delete操作符重載
- 1.1 new和delete操作符重載簡介
- 1.2 靜態(tài)存儲區(qū)中創(chuàng)建動態(tài)對象
- 1.3 在指定的地址上創(chuàng)建C++對象
- 2 new[]和delete[]操作符重載
1 new和delete操作符重載
1.1 new和delete操作符重載簡介
new/delete的本質(zhì)是C++預(yù)定義的操作符,C++對這兩個(gè)操作符做了嚴(yán)格的行為定義:
- new:
- 獲取足夠大的內(nèi)存空間(默認(rèn)為堆空間)。
- 在獲取的空間中調(diào)用構(gòu)造函數(shù)創(chuàng)建對象。
- delete:
- 調(diào)用析構(gòu)函數(shù)銷毀對象。
- 歸還對象所占用的空間(默認(rèn)為堆空間)。
在C++中能夠重載new/delete操作符:
- 全局重載(不推薦)
- 局部重載(針對具體類進(jìn)行重載)
重載new/delete的意義在于改變動態(tài)對象創(chuàng)建時(shí)的內(nèi)存分配方式。
new和delete的重載方式:
需要注意的點(diǎn):
- new操作符重載函數(shù)返回后編譯器會自動調(diào)用構(gòu)造函數(shù)。
- delete操作符重載函數(shù)調(diào)用前編譯器會自動調(diào)用析構(gòu)函數(shù)。
1.2 靜態(tài)存儲區(qū)中創(chuàng)建動態(tài)對象
#include <iostream> #include <string>using namespace std;class Test {static const unsigned int COUNT = 4;static char c_buffer[];static char c_map[];int m_value; 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);cout << "succeed to allocate memory: " << ret << endl;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);if( (flag == 0) && (0 <= index) && (index < COUNT) ){c_map[index] = 0;cout << "succeed to free memory: " << p << endl;}}} };char Test::c_buffer[sizeof(Test) * Test::COUNT] = {0}; char Test::c_map[Test::COUNT] = {0};int main(int argc, char *argv[]) {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; }1.3 在指定的地址上創(chuàng)建C++對象
解決方案:
- 在類中重載new/delete操作符。
- 在new的操作符重載函數(shù)中返回指定的地址。
- 在delete操作符重載中標(biāo)記對應(yīng)的地址可用。
編程實(shí)驗(yàn):自定義動態(tài)對象的存儲空間
#include <iostream> #include <string> #include <cstdlib>using namespace std;class Test {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 ){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(int i=0; i<c_count; i++){if( !c_map[i] ){c_map[i] = 1;ret = c_buffer + i * sizeof(Test);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(int argc, char *argv[]) {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; }2 new[]和delete[]操作符重載
new[]/delete[]和new/delete完全不同:
- 動態(tài)對象數(shù)組創(chuàng)建通過new[]完成。
- 動態(tài)對象數(shù)組的銷毀通過delete[]完成。
- new[]/delete[]能夠被重載,進(jìn)而改變內(nèi)存管理方式。
new[]/delete[]的重載方式:
注意事項(xiàng):
- new[]實(shí)際需要返回的內(nèi)存空間可能比期望的要多。
- 對象數(shù)組占用的內(nèi)存中需要保存數(shù)組信息。
- 數(shù)組信息用于確定構(gòu)造函數(shù)和析構(gòu)函數(shù)的調(diào)用次數(shù)。
編程實(shí)驗(yàn):動態(tài)數(shù)組的內(nèi)存管理
#include <iostream> #include <string> #include <cstdlib>using namespace std;class Test {int m_value; public:Test(){m_value = 0;}~Test(){}void* operator new (unsigned int size){cout << "operator new: " << size << endl;return malloc(size);}void operator delete (void* p){cout << "operator delete: " << p << endl;free(p);}void* operator new[] (unsigned int size){cout << "operator new[]: " << size << endl;return malloc(size);}void operator delete[] (void* p){cout << "operator delete[]: " << p << endl;free(p);} };int main(int argc, char *argv[]) {Test* pt = NULL;pt = new Test;delete pt;pt = new Test[5];delete[] pt;return 0; }參考資料:
總結(jié)
以上是生活随笔為你收集整理的C++中的new和delete操作符重载的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。