1:C++标准说:An allocation function shall be a class member function or a global function; a program is ill-formed if an allocation function is declared in a namespace scope other than global scope or declared static in global scope.
必须是全局函数或类成员函数,而不能是全局之外的名字空间或static全局函数。
2:new operator的行为
对于如下代码:
2 ……其他代码……
3 delete p;
编译器将生成如下代码:
2 如果构造foo不会抛出异常 // 即foo的构造函数后面显式的声明了 throw()
3 在p指向处构造foo(参数1,参数2,……);
4 return p;
5 否则
6 try
7 {
8 在p指向处构造foo(参数1,参数2,……);
9 return p;
10 }
11 catch()
12 {
13 调用 operator delete( void* p, 参数1,参数2,…… );
14 throw;
15 }
16 ……其他代码……
17 调用 operator delete( void* p );
从上面的描述可以看出两点:
a. 除了第一个参数外,其它参数和 operator new 都相同的 operator delete 称为相匹配的 operator delete
b. 相匹配的 operator delete 仅在 operator new 成功,对象构造失败时被调用。而其他地方则一直调用 operator delete( void* p )。
(如果不这么设计的话,编译器得为每一个p绑定当初调用它的operator new相匹配的operator delete的地址,以及当初调用时的实参,汗!!! )
3:全局形式的operator new伪代码:
2 {
3 if( 0 == size ) // 须要注意
4 size = 1;
5
6 while(1)
7 {
8 分配size字节内存;
9 if(分配成功)
10 return 指向内存的指针;
11
12 new_handler globalhandler = set_new_handler(0);
13 set_new_handler(globalhandler);
14
15 if( globalhandler )
16 (*globalhandler)();
17 else
18 throw std::bad_alloc();
19 }
20 }
21 void operator delete( void* raw )
22 {
23 if( 0 == raw ) // 须要注意
24 return;
25
26 }
27
须要说明的是,编译器本身就隐含着一个 void* operator new( size_t ),所以重载全局operator new必须加其他参数以示区别。
一般重载分配函数时都会重载三个,分别是 void* operator new( size_t, …… ),void operator delete( void*, …… ),以及一般形式的 void operator delete( void* )。
4. set_new_handler的作用
set_new_handler设置一个函数,此函数将在分配内存失败时被调用,见3中的代码。
从3中的代码还能看得出,new_handler必须有主动退出的功能,否则就会导致operator new内部死循环。因此newhandler的一般形式是:
须要说明的是,没有类形式的set_new_handler,但这也无所谓,你可以自己写。(见《Effective C++ 2e》条款7)
2 {
3 if( 有可能使得operator new成功(比如释放部分内存) )
4 {
5 做有可能使得operator new成功的事
6 return;
7 }
8 // 主动退出
9 或 abort/exit 直接退出程序
10 或 set_new_handler(其他newhandler);
11 或 set_new_handler(0)
12 或 throw bad_alloc()或派生类 // 这一种比较好,不粗鲁的关闭程序,也不更改其他设置
13 }
5. 类形式的operator new伪代码:
在类中声明operator new和operator delete函数,则在调用new和delete分配类对象时,会自动调用类中的operator new和operator delete替换全局库中的
operator new 和operator delete版本。这些函数隐含式静态函数,也可以显示的指定为静态函数。当然如果想使用全局的new版本,则可以用::new的形式。
2 {
3
4 static void* operator new( size_t size );
5 static void operator delete( void* raw );
6 };
7 void* base::operator new( size_t size )
8 {
9 if( sizeof(base) != size ) // 须要注意
10 return ::operator new(size);
11
12 类似于3 // 注意“没有类形式的set_new_handler”
13 }
14 void base::operator delete( void* raw )
15 {
16 if( sizeof(base) != size ) // 须要注意
17 {
18 ::operator delete(raw);
19 return;
20 }
21 同3
22 }
23
原文地址:http://blog.vckbase.com/bruceteen/archive/2009/05/27/37427.html