在编码过程中,我们常用new来分配堆内存.
MyClass *p = new Myclass;
在这个过程中,实际上经历了3个步骤:
1.调用operator new 分配堆内存;
void *pV = operator new(sizeof(MyClass))
2.调用MyClass的构造函数
MyClass::MyClass();
3.调用placement new 返回类对应指针
MyClass *p = new(pV)MyClass;
new不能够被重载,只有operator new才能够被重载,operator new有6种形式:
//内存分配失败抛异常
void *operator new(std::size_t count)throw(std::bad_alloc);
void operator delete(void *) throw();
//内存分配失败不会抛出异常
void *operator new(std::size_t count, const std::nothrow_t&)throw();
void operator delete(void*, const nothrow_t&) throw();
//placement版本,不可被重载
void *operator new(std::size_t count, void *ptr) throw(){ return ptr; };
//对应的数组版本
void *operator new[](std::size_t count)throw(std::bad_alloc);
void operator delete[](void*) throw();
void *operator new[](std::size_t count, const std::nothrow_t&) throw();
void operator delete[](void* p, void*) throw() { }
void* operator new[](size_t, void* ptr) throw() { return ptr; }
void operator delete[](void* p, void*) throw() { }
通过对operator new的重载,可以定制自己的内存分配函数。
void* operator new(unsigned int size)
{
cout<<"Haha,this is my operator new"<<endl;
char * tmp_p = (char*)malloc(size);
return tmp_p;
}
placement new 的作用是在一个已经分配好的内存中(栈和堆都可以)构造一个新的对象。
placement new 原型中void*p实际上就是指向一个已经分配好的内存缓冲区的的首地址。
placement new实际就是直接使用之前已经分配好的内存,适合那些对时间要求比较高,长时间运行不希望被打断的应用程序。
#include <iostream>
using namespace std;
enum Rank { demoted = 0, promoted = 1 };
//operator new,用num统计分配内存次数
void *operator new(std::size_t count, Rank, int , int, int)
{
cout<<"This is my operator new"<<endl;
static int num = 0;
void * tmp_p = malloc(count);
++num;
cout<<"allocate times: "<<num<<endl;
return tmp_p;
}
void operator delete(void *mem)
{
cout<<"This is my operator delete"<<endl;
static int num = 0;
free(mem);
++num;
cout<<"release times: "<<num<<endl;
}
void operator delete(void *mem, Rank, int , int, int)
{
cout<<"This is my operator delete with parameters"<<endl;
static int num = 0;
free(mem);
++num;
cout<<"release times: "<<num<<endl;
}
class MyClass
{
public:
MyClass()
{
cout<<"This is MyClass constructor"<<endl;
}
~MyClass()
{
cout<<"This is MyClass destructor"<<endl;
}
int var_;
};
int main()
{
//直接使用new, delete
MyClass* const myClass_p = new (demoted,1,2,3) MyClass();
delete myClass_p;
//冒似不能直接用带参数的delete
//delete(demoted,1,2,3) myClass_p;
cout<<"***********************************************************************"<<endl;
//调用operator new和placement new
void * void_p = operator new(sizeof(MyClass),demoted,1,2,3);
MyClass *myClass_p_2 = new(void_p)MyClass();
//operator placement new
//MyClass *myClass_p_2 = (MyClass*)(operator new(sizeof(MyClass),void_p));
myClass_p_2->~MyClass();
operator delete (myClass_p_2);
//带参数的delete
//operator delete (myClass_p_2,demoted,1,2,3);
return 1;
}