18.5 重载全局new、delete、定位new及重载等

一:重载全局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();
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值