Abstact
之前看侯捷老师的C++面向对象开发上。老师讲了一个知识点,如下图:
在他的C++面向对象高级编程(下)课程中,侯捷老师讲了重载operator new,operator delete。这篇blog主要实现重载operator new/delete。并进行验证上图。Let`s go
Code:
下面是相应的代码。重载了operator new/delete/new[]/delete[]。
// .h
#include<iostream>
#include<cstdlib>
using std::cout;
using std::endl;
class Foo {
public:
int _id;
long _data;
Foo() :_id(0) { cout << "default ctor this = " << this << " id=" <<_id<<endl; }
Foo(int i) :_id(i) { cout << "ctor this= " << this << " id=" << _id<<endl; }
~Foo() { cout << "dtor this= " << this << " id= " << _id<<endl; }
static void* operator new(size_t size);
static void operator delete(void* pdead,size_t size);
static void* operator new[](size_t size);
static void operator delete[](void*pdead,size_t size);
};
void * Foo::operator new(size_t size)
{
Foo* p = (Foo*)malloc(size);
cout << "void * Foo::operator new(size_t size),size= " << size<<"p = "<<p << endl;
return p;
}
inline void Foo::operator delete(void * pdead, size_t size)
{
cout << " void Foo::operator delete(void * pdead, size_t size),pdead = "<<pdead<<" size= "<<size<<endl;
free(pdead);
}
inline void * Foo::operator new[](size_t size)
{
Foo* p = (Foo*)malloc(size);
cout << "void * Foo::operator new[](size_t size)" << size<<" p = "<<p << endl;
return p;
}
inline void Foo::operator delete[](void * pdead, size_t size)
{
cout << " void Foo::operator delete[](void * pdead, size_t size),pdead = " << pdead << " size= " << size << endl;
free(pdead);
}
// .cpp
int main()
{
Foo* p = new Foo();
delete p;
Foo* ppp= new Foo[4];
delete[] ppp;
}
Result
下图是程序所打印出来的。
Foo* p = new Foo();
delete p;
第一段代码使用new生成了一个Foo对象。在图中:是先执行operator new,在执行构造函数。
delete p是先执行析构函数,再执行operator delete。
Foo对象有int ,long两个数据,所以sizeof(Foo)=8。对应operator new的第一参数size_t size =8。operator delete的第二参数size_t size=8.都是符合的。
Foo* ppp= new Foo[4];
delete[] ppp;
第二段代码:使用new[] 生成了4个Foo对象。首先:是执行operator new,再执行4次构造函数。
对应于delete,也是先执行4次析构函数,再执行operator delete。
传入的size_t size应该是4*sizeof(Foo)=32,但是 传入 operator new[]/delete[] 却是36。当然:侯捷老师也讲了这个。可以看看下图:
总结
总结下CPP里的new delete的知识.
CPP里对与生成对象,删除对象就是走最上图的流程。首先分配内存,在执行析构函数。
所以:学习new的知识时,要清楚这个。
new 分配内存,执行析构函数.
operator new 分配内存
placement new:operator new的重载。CPP提供的版本:是让你提供内存,而不是操作系统分配内存。当然:你也可以重载其他形式。
void operator new(size_t size){
// malloc 分配内存
}
void operator new(size_t size,void* start){
return start;
}
下面是侯捷老师举个一个重载placement new的例子。还是STL的例子。很有权威性。
在string里,重载为
static void* operator new(size_t,size_t extra)
stackoverflow:what uses are there for placement new:列出了使用placement new 的例子。有兴趣的同学可以去看看。