loki庫中DefaultAlloc中介紹了c++目前支持的new 和 delete相關的操作
我們知道new操作實際包含兩個步驟:operator new:分配內存,構造函數調用。
而operator new我們是可以重載的
相對的delete操作也包含兩個步驟,析構函數調用,析構內存.
另外簡單瞭解下分配內存過程:vs實現中會調用C的mallo,再調用操作系統的HeapAlloc,操作系統分配內存有HeapAlloc和virtualAlloc,分配大內存可以考慮virtualAlloc。一般情況下建議使用new和delete即可,編譯器內部會適當的調用合適的api接口
編譯器類型,版本獲取,以vs爲例
#elif (_MSC_VER >= 1400)
return "Microsoft 8.0 or higher";
#elif (_MSC_VER >= 1300)
return "Microsoft 7";
#elif (_MSC_VER >= 1200)
return "Microsoft 6";
#elif (_MSC_VER)
return "Microsoft, but a version lower than 6";
new的重載形式
1、void * operator new ( std::size_t size ) throw(std bad_alloc)
我們調用的最常見形式,舉例
CTestPtr* pA1 = new CTestPtr;
2、void * operator new ( std::size_t size, const std::nothrow_t & nt ) throw ()
不拋出異常的形式,nothrow_t是一個結構體,而std::nothrow是一個對象,通過類型識別函數重載調用的這個函數
struct nothrow_t
{ // placement new tag type to suppress exceptions
};
extern const nothrow_t nothrow; // constant for placement new tag
舉例
CTestPtr* pA2 = new(std::nothrow)CTestPtr;
3、void * operator new ( std::size_t size, void * place )
在place內存位置調用構造函數,使用舉例。new的調用都是new(第二個參數),第一個參數固定爲size_t
void* pA = ::operator new(sizeof(CTestPtr));
CTestPtr* pa = new(pA)CTestPtr;
delete的重載形式
1、void operator delete ( void * place, std::size_t size ) throw ()
2、void operator delete ( void * place, const std::nothrow_t & nt ) throw()
3、void operator delete ( void * place1, void * place2 )
調用delete操作符是不會調用析構函數的
CTestPtr* pA1 = new CTestPtr;
::operator delete(pA1); // 調用的是delete接口,釋放內存,不會調用析構函數
// delete pA1;// 會先調用析構函數,再調用delete釋放內存
// delete(PA1)和delete pA1效果一樣,這個沒怎麼想明白