C++通过new来在堆上创建对象,这一过程分为两步:
1.分配一块大小合适的内存
2.调用构造函数初始化对象
C++允许重载operator new,但是请注意,这个重载的operator new只需且只能完成第一步的工作,即:分配内存;初始化对象的任务由编译器负责完成。
#include <iostream>
using namespace std;
class A{
public:
A()
{
cout<<"A constructor"<<endl;
}
~A()
{
cout<<"A destructor"<<endl;
}
};
void* operator new(size_t size)
{
cout<<"call operator new"<<endl;
if(size == 0) //编译器自带的operator new也允许分配size为0的内存
{
size = 1;
}
return malloc(size);
}
void operator delete(void* ptr)
{
cout<<"call operator delete"<<endl;
if(ptr == 0) return; //C++允许delete空指针
free(ptr);
}
int main(){
A *pa = new A();
delete pa;
return 0;
}
允许程序输出:
call operator new
A constructor
A destructor
call operator delete
可见定义了operator new和delete后,分配和释放内存都是通过自定义的new和delete进行的,虽然自定义的new和delete没有调用构造和析构函数,但是编译器会进行调用。
可以为类定义自己的operator new和delete:
#include <iostream>
using namespace std;
class A{
public:
A()
{
cout<<"A constructor"<<endl;
}
~A()
{
cout<<"A destructor"<<endl;
}
void* operator new(size_t size)
{
cout<<"call A::operator new"<<endl;
if(size == 0)
{
size = 1;
}
return malloc(size);
}
void operator delete(void* ptr)
{
cout<<"call A::operator delete"<<endl;
if(ptr == 0) return;
free(ptr);
}
};
class B{
public:
B()
{
cout<<"B constructor"<<endl;
}
~B()
{
cout<<"B destructor"<<endl;
}
};
int main(){
A *pa = new A();
delete pa;
B* pb = new B();
delete pb;
return 0;
}
允许程序输出:
call A::operator new
A constructor
A destructor
call A::operator delete
B constructor
B destructor
可见类A调用自己的operator new和delete
类B由于没有自定义的operator new和delete,所以还是会调用默认的new和delete