目錄
- 1、通過重載獲得內存管理權
- 2、容器的內存管理
- 3、重載new、array new、replacement new,接管內存控制權
- 1、重載全局::operator new / ::operator delete以及array版本
- 2、在類里面去重載
1、通過重載獲得內存管理權
之前的幾章學習,是紅色的路線。此時內存管理權限不在我們手中。
接下來,通過class內部的重載operator new/delete,我們可以獲得內存管理權力。
注意operator new/delete,這張PPT里面有兩個。一個是在class內部重載,還有一個是全局的重載。
2、容器的內存管理
當我們將元素放入容器中,容器顯然也要做出與上面相似的內存分配的動作。
容器講構造和析構函數包裝在construct()與destroy()中。內存的分配和釋放動作拉入分配器中。
分配器在分配內存的時候與上圖的紅色線路是一樣的。
分配器所做的就是一些復雜的內存管理。
3、重載new、array new、replacement new,接管內存控制權
已知,我們可以從全局或者類里面去重載。
1、重載全局::operator new / ::operator delete以及array版本
注意這里的重載函數相對于原來的函數只是多了一個打印信息操作。
這里只是做一個接口的示范規格。
void* myAlloc(size_t size)
{return malloc(size);
}
void myFree(void* ptr)
{return free(ptr);
}他們不能被聲明于一個namespace內
inline void* operator new(size_t size)
{cout << "global new()" << endl;return myAlloc(size);
}inline void operator delete(void* ptr)
{cout << "global delete()" << endl;myFree(ptr);
}inline void* operator new[](size_t size)
{cout << "global new[]()" << endl;return myAlloc(size);
}
inline void operator delete[](void* ptr)
{cout << "global delete[]()" << endl;myFree();
}
2、在類里面去重載
我們在類里面寫好兩個重載函數:
class Foo {
public:void* operator new(size_t);void operator delete(void*,size_t);
};
注意上面的delete函數的第二個參數size_t是可有可無的。
同時也需要注意,這里的operator new和 operator delete 函數是靜態的,要加上static。因為在new一個對象的時候我們手上是沒有對象的,也就是說無法通過對象調用一般的函數。加上static就可以不通過對象而直接調用這兩個函數了。這是一個細節。
在我們進行new和delete操作時,由編譯器調用:
Foo* p = new Foo;
...
delete p;
編譯器將上述代碼轉換為如下格式:
try {void* mem = operator new(sizeof(Foo));p = static_cast<Foo*>(mem);//調用構造函數p->Foo::Foo();
}//調用析構函數
p->~Free();
operator delete(p);
同理array的版本如下:
Foo* p = new Foo[N];
...
delete [] p;class Foo {
public:void* operator new[](size_t);void operator delete[](void*,size_t);
};