operator new和operator delete学习总结
这块内容很多很多,那就捡几个重要的地方说说吧,主要目的是为了在遗忘的时候给自己提个醒,呵呵。
1。new和delete的重载函数都是static函数,你可以在声明的时候写上去,也可以不写(编译器自动为你添加),但是事实是无法更改的,它们都是static的。
2。new和delete必须形式上配对,且里面做的内容也要配对
void* operator new(size_t size, const char*, int);//调用形式为new("wokao",34) ;
void operator delete(void *p, const char*, int);//这个delete与上面的那个new配对
void operator delete(void *p, size_t, const char*, int)//这个delete与上面的那个new不配对
3。new和delete的标准形式是:
void* operator new(size_t size);
void operator delete(void* p);
或void operator delete(void* p,size_t size);//这个delete可以验证if( sizeof(X)!=size )
4。new可以被重载出其他的样式来;而delete重载时,如果有其他样式出现,那是为了配合new的新样式,与此同时也必须得有标准的delete样式,因为我们最后delete *p的时候调用的是标准的delete样式,而那个非标准的只是为了在构造函数抛出异常时让系统调用与新样式的new配套的新样式的delete。
5。只有基类的析构函数被声明为virtual时(如果你没有在基类中写析构函数而是利用默认的或者即便写了却忘了加virtual都是不可以的),才可以通过基类的指针(实则指向子类)来delete,达到调用子类delete的目的。
6。不论你重载不重载,本质上new都是调用::operator new(size)这个全局函数来分配恰当的内存空间,可以在调用new之前通过set_new_handler函数来设置配置内存失败的回调函数。
7。new重载函数中的size至少是1,即便类没有任何成员变量。
8。new的顺序:new->基类的构造函数(在进入基类构造函数之前当然需要先根据初始化列表来初始化基类的部分成员变量)->子类的构造函数(在进入基类构造函数之前当然需要先根据初始化列表来初始化基类的部分成员变量)
9。delete的顺序:子类的析构函数->基类的析构函数->delete
10。重载new运算符时最好要让标准的new的调用形式露出来
void* operator new(size_t size,char*);void* operator new(size_t size);
或void* operator new(size_t size,char* =NULL);
11。写一个new,就最好写一个与之配套的delete。
12。对于new[]和delete[]的重载,也完全没啥区别,就是换了个名称,除此之外,再无其他特别之处了。