過載operator new和 operator delete
阿新 • • 發佈:2018-11-15
1.建立類Foo
在類Foo中過載operator new和 operator delete。
class Foo { private: int _id; public: Foo() :_id(0) { cout << "Default Construct " << this << " id = " << _id << endl; } Foo(int id) :_id(id) { cout << "Construct " << this << " id = " << _id << endl; } ~Foo() { cout << "Destructor " << this << endl; } static void *operator new (size_t size) { Foo *p = (Foo*)malloc(size); return p; } static void operator delete(void *p, size_t size) { free(p); } static void *operator new[](size_t size) { Foo *p = (Foo*)malloc(size); return p; } static void operator delete[](void *p, size_t size) { free(p); } };
2.測試程式
int main()
{
cout << "sizeof(Foo) = " << sizeof(Foo) << endl;
Foo *p = new Foo();
delete p;
Foo *pArray = new Foo[5];
delete[]pArray;
system("pause");
}
3.執行結果
4.結果分析
類Foo的大小是4,原因是包含int型別的資料_id。
過載operator new和 operator delete時,接管了記憶體的申請和釋放,此處簡單的呼叫malloc和free,以後可能通過記憶體池管理記憶體,提高效率。
Foo *p = new Foo()中,呼叫*operator new時傳入的size為4。
Foo *pArray = new Foo[5]中,呼叫*operator new[]時傳入的size為24。
對陣列而言,析構的順序和構造的順序相反。
5.擴充套件
operator new的過載版本可以有多個引數,但第一個引數必須是size_t。
static void *operator new (size_t size, void* start) { return start; } static void *operator new (size_t size, long extra) { return malloc(size + extra); } static void *operator new (size_t size, long extra, char init) { return malloc(size + extra); }
operator delete也可以有多個過載版本,但只有當new所呼叫的建構函式丟擲異常,才會呼叫這些過載版本。即使operator delete未能一一對應於operator new,也不會出現任何報錯,只是意味著放棄處理建構函式丟擲的異常。
static void operator delete(void *, void *)
{
}
static void operator delete(void *, long)
{
}
static void operator delete(void *, long, char)
{
}
標準庫中,string類已提供的placement new(size_t size, long extra)的過載形式。