#include<iostream.h>
#include<windows.h>
#include<stddef.h>
class opNew
{
private:
static HANDLE s_hHeap;
static UINT s_uNumAllocsInHeap;
public:
opNew();
~opNew();
void * operator new(size_t size);
void operator delete(void *p);
};
HANDLE opNew::s_hHeap = NULL;
UINT opNew::s_uNumAllocsInHeap = 0;
opNew::opNew()
{
cout << "Constructor:" << endl;
cout << s_hHeap << endl;
cout << s_uNumAllocsInHeap << endl;
}
opNew::~opNew()
{
cout << "DeConstructor:" << endl;
cout << s_hHeap << endl;
cout << s_uNumAllocsInHeap << endl;
}
void * opNew::operator new(size_t size)
{
if(s_hHeap == NULL)
{
s_hHeap = HeapCreate(HEAP_GENERATE_EXCEPTIONS, 0, 0);
if(s_hHeap == NULL)
return NULL;
}
void *p = HeapAlloc(s_hHeap, HEAP_ZERO_MEMORY, size);
if(p != NULL)
{
s_uNumAllocsInHeap++;
}
return p;
}
void opNew::operator delete(void *p)
{
if(HeapFree(s_hHeap, 0, p))
{
s_uNumAllocsInHeap--;
}
if(s_uNumAllocsInHeap == 0)
{
if(HeapDestroy(s_hHeap))
s_hHeap = NULL;
}
}
void test1()
{
opNew op1;
}
void test2
{
opNew *op1 = new opNew;
opNew *op2 = new opNew;
opNew *op3 = new opNew;
}
void test3
{
opNew *op1 = new opNew;
opNew *op2 = new opNew;
opNew *op3 = new opNew;
delete op3;
delete op2;
delete op1;
}
void main()
{
test1();
test2();
test3();
system("PAUSE");
}
上面只是一个重载new以及delete的简单例子。但是从中我也发现了一些东西。
当我们运行程序后,会发现 test1 test3 调用了析构函数。但是test2没有调用。这是为什么呢?
1.
opNew op1;
是在栈上位变量分配内存。而在栈上分配的内存,在出了变量的作用域后会自动销毁。所以test1调用完之后,对象op1也就销毁了,因此会自动调用析构函数。
2.
opNew *op1 = new opNew;
opNew *op2 = new opNew;
opNew *op3 = new opNew;
则不同了。我们重载了new(*),是在堆上分配内存,在你手动销毁它之前是不会销毁的。所以test2的调用结束后,虽然出了局部变量(对象)op1(2,3)的作用域,但是因为内存没有被销毁,所以变量(对象)没有被销毁。因此也就不会自动调用析构函数了。
*当然了,系统默认的new也是在堆上分配内存的。
3.
opNew *op1 = new opNew;
opNew *op2 = new opNew;
opNew *op3 = new opNew;
delete op3;
delete op2;
delete op1;
因为我们调用了delete来销毁分配的内存,对象也被销毁了。所以会调用析构函数。
总之,我们平时说堆栈,其实是2个不同的概念。在写程序的时候,涉及到内存管理的时候,应该要区分这2个概念。