[C++再學習系列] 深入new/delete:Operator new的全域重載
http://blog.csdn.net/zhenjing/archive/2009/07/16/4354880.aspx
Operator
new
的全域重載
我們經常看到這麼一句話:
operator new
可以重載,
placement new
不可重載。其實此處所說的不可重載應該是指全域的
placement new
不可重載,對於類域中的
placement new
是可以重載的,而且只要重載了任何一種形式的
operator new
都應該順便重載
placement new
, 即
void * operator new(std::size_t
count, void *ptr)
。
操作符重載一般用於特定類型,名字解析過程同一般的函數重載。
Operator new
由於其特殊性,編譯器提供了預設提供
6
種全域重載形式,同時還允許使用者提供自訂的全域
operator new
,其參數甚至可以和全域版本一樣,除全域
placement new
外。對於類域,任何形式的
new
都是可以重載的,包括
placement
new
形式。
全域的
operator new(
函數
)
有六種重載形式
void
*operator
new(std::size_t count)
throw(std::bad_alloc);
//
一般的版本
void
*operator
new(std::size_t count,
//
相容早版本的
new
const std::nothrow_t&) throw();
//
記憶體配置失敗不會拋出異常
void
*operator
new(std::size_t count, void *ptr) throw();
//placement
版本
void
*operator
new[](std::size_t count)
//
throw(std::bad_alloc);
void
*operator
new[](std::size_t count,
//
const std::nothrow_t&) throw();
void
*operator
new[](std::size_t count, void *ptr) throw();
重載
operator new
規則
重載
operator new
的參數個數是可以任意的
,
只需要保證第一個參數為
size_t,
傳回型別為
void *
即可
,
而且其重載的參數類型也不必包含自訂類型
.
更一般的說
, operator
new
的重載更像是一個函數的重載
,
而不是一個操作符的重載
.
如:
全域重載樣本:
void*
operator
new(size_t size)
//
重載成功
{
printf("global new\n");
return malloc(size);
//return ::operator new(size);
//
遞迴調用提示
(warning)
}
//void
*operator
new(std::size_t size, void *ptr) //
無法重載
//{
//
printf("global new\n");
//
return ::operator new(size,ptr);
//}
void
* operator
new(size_t size, const std::nothrow_t& e) //
重載成功
,
遞迴調用提示
(warning)
{
printf("global new\n");
return ::operator new(size, e);
}
一般形式的
operator new
重載樣本:
void
* operator
new(size_t size, int x, int y, int z)
{
...
}
X *
pX = new (1,
2, 3) X;
char
data[1000][sizeof(foo)];
inline
void*
operator new(size_t size, int n)
{
return data[n];
}
就可以使用這樣有趣的文法來建立對象
:
foo
*p=new(6)
foo(); //
把對象建立在
data
的第六個單元上