在类Foo中重载operator new和 operator delete。
class Foo
{
private:
int _id;
public:
Foo() :_id(0)
{
cout << "Default Construct " << this << " id = " << _id << endl;
}
Foo(int id) :_id(id)
{
cout << "Construct " << this << " id = " << _id << endl;
}
~Foo()
{
cout << "Destructor " << this << endl;
}
static void *operator new (size_t size)
{
Foo *p = (Foo*)malloc(size);
return p;
}
static void operator delete(void *p, size_t size)
{
free(p);
}
static void *operator new[](size_t size)
{
Foo *p = (Foo*)malloc(size);
return p;
}
static void operator delete[](void *p, size_t size)
{
free(p);
}
};
int main()
{
cout << "sizeof(Foo) = " << sizeof(Foo) << endl;
Foo *p = new Foo();
delete p;
Foo *pArray = new Foo[5];
delete[]pArray;
system("pause");
}
类Foo的大小是4,原因是包含int类型的数据_id。
重载operator new和 operator delete时,接管了内存的申请和释放,此处简单的调用malloc和free,以后可能通过内存池管理内存,提高效率。
Foo *p = new Foo()中,调用*operator new时传入的size为4。
Foo *pArray = new Foo[5]中,调用*operator new[]时传入的size为24。
对数组而言,析构的顺序和构造的顺序相反。
operator new的重载版本可以有多个参数,但第一个参数必须是size_t。
static void *operator new (size_t size, void* start)
{
return start;
}
static void *operator new (size_t size, long extra)
{
return malloc(size + extra);
}
static void *operator new (size_t size, long extra, char init)
{
return malloc(size + extra);
}
operator delete也可以有多个重载版本,但只有当new所调用的构造函数抛出异常,才会调用这些重载版本。即使operator delete未能一一对应于operator new,也不会出现任何报错,只是意味着放弃处理构造函数抛出的异常。
static void operator delete(void *, void *)
{
}
static void operator delete(void *, long)
{
}
static void operator delete(void *, long, char)
{
}
标准库中,string类已提供的placement new(size_t size, long extra)的重载形式。