首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 基礎

C++ 重載 new/delete 運算符:自定義記憶體管理策略

     編輯:C++ 基礎

為什麼要重載記憶體管理運算符?

C++ 內建的 new、new[]、delete、delete[] 對大多數場景已足夠。但在特定需求下——如實現記憶體池、追蹤記憶體洩漏、自定義分配策略(對齊、分區、共享記憶體)等——重載這些運算符成為必要手段。

重載形式可為類成員函數或全域函數,兩者語法略有不同但核心簽名一致。

重載 new / new[] 運算符

成員函數形式

void* ClassName::operator new(size_t size) {
    // 自定義分配邏輯
    return allocated_memory;
}

全域函數形式

void* operator new(size_t size) {
    // 全域自定義分配邏輯
    return allocated_memory;
}

關鍵規則:

  • 返回型別必須為 void*
  • 第一個參數必須為 size_t,表示請求分配的位元組數(new[] 時為總大小)
  • 可額外增加參數,但必須提供預設值
  • size_t 通常定義為 typedef unsigned int size_t;(在 <cstdio> 中)

重載 delete / delete[] 運算符

成員函數形式

void ClassName::operator delete(void* ptr) {
    // 自定義釋放邏輯
}

全域函數形式

void operator delete(void* ptr) {
    // 全域自定義釋放邏輯
}

關鍵規則:

  • 返回型別為 void
  • 必須接受一個 void* 參數,指向待釋放的記憶體
  • 配對使用:重載 new 通常需重載對應的 delete

使用示例

class C {
public:
    void* operator new(size_t size) {
        cout << "Custom new called, size: " << size << endl;
        return malloc(size);  // 或其他分配策略
    }
    void operator delete(void* ptr) {
        cout << "Custom delete called" << endl;
        free(ptr);
    }
};

int main() {
    C* c = new C;  // 調用 C::operator new
    // ...
    delete c;      // 調用 C::operator delete
    return 0;
}

若類未定義重載,編譯器自動調用內建運算符。

進階場景與注意事項

  • 記憶體池:預先分配大塊記憶體,new 從池中切分,delete 歸還池中,減少系統調用開銷
  • 偵錯追蹤:在分配/釋放時記錄堆疊、檔案、行號,定位洩漏
  • 對齊控制:針對 SIMD、GPU 等需對齊記憶體的場景
  • 拋出異常:分配失敗時應拋出 std::bad_alloc,符合標準行為
  • 配對原則:new/delete、new[]/delete[] 必須成對重載,避免未定義行為

總結

重載 new/delete 賦予類完全的記憶體管理自主權,是高效能、嵌入式、遊戲引擎等領域的核心技能。但濫用會增加複雜度,僅在確有必要時使用,且務必嚴格遵循配對與異常安全原則。

  1. 上一篇文章:
  2. 下一篇文章:
  • --热点文章
  • Copyright © 程式碼之家 All Rights Reserved