一:重载全局operator new和operator delete操作符
#include <iostream>
using namespace std;
void* operator new(size_t size)
{
return malloc(size);
}
void* operator new[](size_t size) //数组版本
{
return malloc(size);
}
void operator delete(void* phead)
{
free(phead);
}
void operator delete[](void* phead)
{
free(phead);
}
class A
{
public:
int m_i;
int m_j;
A()
{
cout << "A::A()" << endl;
}
~A()
{
cout << "A::~A()" << endl;
}
public:
void* operator new(const size_t size)
{
A* ppoint = (A*)malloc(size);
return ppoint;
};
void* operator new[](const size_t size) //数组版本
{
A* ppoint = (A*)malloc(size);
return ppoint;
};
void operator delete(void* phead)
{
free(phead);
};
void operator delete[](void* phead)
{
free(phead);
};
};
void func()
{
int* pint = new int(10);
delete pint;
char* parr = new char[20];
delete[] parr;
A* pa1 = new A();
delete pa1;
A* pa2 = new A[5]();
delete[] pa2;
}
int main()
{
func();
}
二:定位new(placement new)
有placement new,但是没有对应的placement delete
功能:在已经分配的原始内存中初始化一个对象;
1、已经分配,定位new并不分配内存,你需要提前将这个定位new要使用的内存分配出来;
2、初始化一个对象(初始化一个对象的内存),我们可以理解成调用这个对象的构造函数;所以,定位new就是能够在一个预先分配好的内存地址上构造一个对象。
格式:
new (地址) 类类型(参数)
#include <iostream>
using namespace std;
class A
{
public:
int m_a;
public:
A() :m_a(10)
{
int test;
test = 1;
}
A(int tmpvalue) : m_a(tmpvalue)
{
int test;
test = 1;
}
~A()
{
int test;
test = 1;
cout << "A::~A()" << endl;
}
//operator new重载
void* operator new(const size_t size)
{
cout << "void* operator new(const size_t size)" << endl;
A* ppoint = (A*)malloc(size);
return ppoint;
}
//定位new操作符的重载
void* operator new(size_t size, void* phead)
{
cout << "void* operator new(size_t size, void *phead)" << endl;
return phead; //收到内存开始地址,只需要原路返回
}
};
void func()
{
void* mymemPoint1 = (void*)new char[sizeof(A)]; //内存必须事先分配出来
A* pmyAobj1 = new(mymemPoint1)A(); //调用无参构造函数,这里并不会额外分配内存
void* mymemPoint2 = (void*)new char[sizeof(A)];
A* pmyAobj2 = new(mymemPoint2)A(10); //调用带一个参数的构造函数,这里并不会额外分配内存
//delete pmyAobj1;
//delete pmyAobj2;
pmyAobj1->~A(); //手工调用析构函数是可以的,但是手工调用构造函数一般不可以
pmyAobj2->~A();
delete[](void*) pmyAobj1;
delete[](void*) pmyAobj2;
}
int main()
{
func();
}
三:多种版本的operator new重载
可以重载很多版本的operator new,只要每个版本参数不同就行,但是第一个参数是固定的,必须为size_t,表示要new对象的sizeof值。
如果自定义了operator new重载,系统将不会生成默认重载。并且,自定义重载不会调用构造函数。
#include <iostream>
using namespace std;
class A
{
public:
int m_a;
public:
A()
{
cout << "A::A()" << endl;
}
~A()
{
cout << "A::~A()" << endl;
}
void* operator new(const size_t size)
{
cout << "void* operator new(const size_t size)" << endl;
return nullptr;
}
void* operator new(const size_t size, int tvp1, int tvp2)
{
cout << "void* operator new(const size_t size, int tvp1, int tvp2)" << endl;
return nullptr;
}
};
void func()
{
A* pa1 = new A();
A* pa2 = new (10, 20) A();
}
int main()
{
func();
}