5 More Effective C++—条款8:(operator new 和 new operator)

本文深入解析C++中new操作符的两种形式:new operator和placement new。解释了它们如何分配和初始化内存,以及如何通过重载operator new进行自定义内存管理。同时,探讨了析构与内存释放的过程,以及数组的特殊操作符new[]和delete[]。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 两种new的区别和联系

C++中的操作符new在执行下面代码时,做了如下两件事。这种操作符叫做"new operator"。对于开辟空间这部分,new operator实际调用了operator new操作符。

1 调用operator new操作符,开辟内存空间。
2 调用构造函数,初始化内存空间。

class MyClass {
}
MyClass *my = new MyClass;

程序员无法重载new operator,但是可以重载operator new,即空间分配函数。

operator new函数通常声明为如下形式——其必须制定分配内存大小。该函数返回一个指针,指向未初始化的内存。size_t指定了内存大小。

void * operator new(size_t size);
void *rawMemory = operator new(sizeof(string));
// init the memory
string *ps = static_cast<string*>(rawMemory);

2 Placement new

不仅分配内存可以手动定制,初始化内存依然可以手动定制。我们调用类的构造函数,并将原始内存初始化,这种行为被称为placement new。

如下代码所示,其调用new operator,来对已经开辟的内存buffer进行初始化。

class MyClass {
	public:
		MyClass(int param);
}
MyClass *createMyClass(void *buffer, int param) {
	return new (buffer) MyClass(param);
}

实际上,new operator隐式调用operator new,利用operator new返回的指针,来进一步调用构造函数来初始化内存。

因此,我们可以定义如下operator new操作符——不开辟空间,直接利用传入的指针。注意,operator new 操作符必须给出第一个内存大小参数。

void * operator new(size_t, void *location) {
	return location;
}

placement new技术在#include < new >或#include <new.h> 中声明。

3 析构与内存释放

创建对象顺序是:开辟空间,初始化内存。删除对象的顺序就要相反。与new相对应,delete也有两种类型的操作符:delete operator 和 operator delete。delete operator调用operator delete来释放空间。

1 调用析构函数
2 删除开辟的内存空间

但是,由于内存空间是由operator new获得的,因此在释放内存时,就不能用经过类型转换的指针,而是使用原始的内存指针。

void *rawMemory = operator new (10 * sizeof(string));
// do something
operator delete(rawMemory);

4 数组

C++相应提供了operator new []和 operator delete[] 操作符用于重载。这两个操作符用于开辟数组空间。

对于new [] operator 和 delete [] operator而言,其调用顺序与单个对象一致,只是在初始化或析构内存空间时,需要为数组中的每个对象执行构造或析构函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值