18.1.6 類特定的new和delete
編譯器看到類類型的new或delete表達式的時候,它查看該類是否有operator new或operator delete成員,如果類定義(或繼承)了自己的成員new和delete函數,則使用那些函數為對象分配和釋放內存;否則,調用這些函數的標准庫版本。
1. 成員new和delete函數
如果類定義了這兩個成員中的一個,它也應該定義另一個。
類成員operator new函數必須具有返回類型void*並接受size_t類型的形參。由new表達式用以字節計算的分配內存量初始化函數的size_t形參。
類成員operator delete函數必須具有返回類型void。它可以定義為接受單個void*類型形參,也可以定義為接受兩個形參,即void*和size_t類型。由delete表達式用被delete的指針初始化void*形參,該指針可以是空指針。如果提供了size_t形參,就用編譯器用第一個形參所指對象的字節大小自動初始化size_t形參。
這些函數隱式為靜態函數,不必顯式地將它們聲明為static,雖然這樣做是合法的。成員new和delete函數必須是靜態的,因為它們要麼在構造對象之前使用(operator new),要麼在撤銷對象之後使用(operator delete),因此,這些函數沒有成員可操縱。像任意其他靜態成員函數一樣,new和delete只能直接訪問所屬類的靜態成員。
2. 數組操作符new[]和操作符delete[]
也可以定義成員operator new[]和operator delete[]來管理類類型的數組。如果這些operator 函數存在,編譯器就使用它們代替全局版本。
3. 覆蓋類特定的內存分配
如果類定義了自己的成員new和delete,類的用戶就可以通過使用全局作用域確定操作符,強制new或delete表達式使用全局的庫函數。
Vector<int> *vec=::new Vector<int>;
::delete vec;
Vector<int> *vec=::new Vector<int>;
::delete vec;即使類定義了自己的類特定的operator new,也調用全局的operator new;delete類似。
如果用new表達式調用全局operator new函數分配內存,則delete表達式也應該調用全局operator delete函數。
template<class T>
class Vector{
public:
Vector():elements(0),first_free(0),end(0){}
void push_back(const T&);
void *operator new[](size_t); //allocate an array
void operator delete[](void*); //delete memory of an array
private:
static std::allocator<T> alloc;
void reallocate();
T* elements; //first element
T* first_free; //behind the last actual element
T* end; //behind vector conent
};
template<class T>
void Vector<T>::push_back(const T& t){
if(first_free==end)
reallocate(); //gets more space and copies existing elements to it
new(first_free) T(t);
++first_free;
}
template <class T>
void Vector<T>::reallocate(){
std::ptrdiff_t size=first_free-elements;
std::ptrdiff_t newcapacity=2*max(size,1);
T* newelements=static_cast<T*>(alloc.operator new[](newcapacity));
uninitialized_copy(elements,first_free,newelements);
for(T *p=first_free;p!=elements;){
alloc.destroy(--p);
}
if(elements)
alloc.operator delete[](elements,end-elements);
elements=newelements;
first_free=elements+size;
end=elements=newcapacity;
}
摘自 xufei96的專欄