Cpp 对象模型探索 / operator new、operator delete、operator new[] 和 operator delete [] 重载
零、前言
? ? ? ?對于函數 operator new 和 operator delete 來說,分為全局重載和局部重載。
全局重載的形式:
void *::operator new(size_t size); void ::operator delete(void *pdata);局部重載的形式:
void *A::operator new(size_t size); void A::operator delete(void *pdata);?
一、operator new 和 operator delete
源碼
#include <iostream>void *operator new(size_t size) {std::cout << "全局的 operator new 重載函數。" << std::endl;return malloc(size); }void operator delete(void *pdata) {std::cout << "全局的 operator delete 重載函數。" << std::endl;free(pdata); }class CTest { public:CTest(){std::cout << "構造函數" << std::endl;}~CTest(){std::cout << "析構函數" << std::endl;} public:static void *operator new(size_t size);static void operator delete(void *pdata); };void *CTest::operator new(size_t size) {CTest *pt = (CTest *)malloc(size);std::cout << "類重載的 operator new 重載函數。" << std::endl;return pt; }void CTest::operator delete(void *pdata) {free(pdata);std::cout << "類重載的 operator delete 重載函數。" << std::endl; }int main() {std::cout << "---------- 類重載 new delete 重載 ----------" << std::endl;CTest *pT1 = new CTest();delete pT1;std::cout << std::endl;std::cout << "---------- 全局 new delete 重載 ----------" << std::endl;CTest *pT2 = ::new CTest();::delete pT2;std::cin.get();return 0; }?
結果
二、operator new [] 和 operator delete []
1、源碼
#include <iostream>void *operator new[](size_t size) {void *p = malloc(size);std::cout << "全局的 operator new[] 重載函數。" << std::endl;std::cout << " 形參大小為 " << size << std::endl;std::cout << " malloc 申請的內存地址為 " << p << std::endl;return p; }void operator delete[](void *pdata) {std::cout << "全局的 operator delete[] 重載函數。" << std::endl;free(pdata); }class CTest { public:CTest(){std::cout << "構造函數" << std::endl;}~CTest(){std::cout << "析構函數" << std::endl;} public:static void *operator new[](size_t size);static void operator delete[](void *pdata); };void *CTest::operator new[](size_t size) {CTest *pt = (CTest *)malloc(size);std::cout << "類重載的 operator new[] 重載函數。" << std::endl;std::cout << " 形參大小為 " << size << std::endl;std::cout << " malloc 申請的內存地址為 " << pt << std::endl;return pt; }void CTest::operator delete[](void *pdata) {free(pdata);std::cout << "類重載的 operator delete[] 重載函數。" << std::endl; }int main() {std::cout << "---------- 類重載 new deletep[] 重載 ----------" << std::endl;CTest *pT1 = new CTest[3];std::cout << " new 返回的內存地址為 " << pT1 << std::endl;delete []pT1;std::cout << std::endl;std::cout << "---------- 全局 new delete[] 重載 ----------" << std::endl;CTest *pT2 = ::new CTest[3];std::cout << " new 返回的內存地址為 " << pT2 << std::endl;::delete []pT2;std::cin.get();return 0; }結果
2、分析
? ? ? ?(1)operator new[] 和 operator delete[] 使用方法和 operator new 和 operator delete 相同。
? ? ? ?(2)由代碼可知,申請包含 3 個元素的數組,執行過程為申請內存 1 次,調用構造函數 3 次,說明在申請內存時會一次性的將數組所需要的內存全部申請完畢。
? ? ? ?(3)上述代碼的執行結果可以發現,由于類 CTest 為空類,故對象占 1B,數組共占 3B,但是傳入 operator new [] 函數的形參為 7,為什么會這樣呢?原因如下圖所示,0x00A31650 是 malloc 函數返回的地址信息,藍框就是包含 3 個對象的數組,紅框則記錄了該數組的大小,正好值為 3 。所以,雖然申請了大小僅僅為 3B 的數組,但是系統需要為其分配 7B 的內存。
? ? ? ?上述多申請的內存在對于自建的數據類型來說是成立的,但是對于C++自帶的數據類型來說則不成立。后者申請內存時不需要前面加入內存來記錄該數組中元素的數量。
?
(SAW:Game Over!)
總結
以上是生活随笔為你收集整理的Cpp 对象模型探索 / operator new、operator delete、operator new[] 和 operator delete [] 重载的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Cpp 对象模型探索 / delete
- 下一篇: 阻塞、非阻塞与同步、异步的区别