看placement new和operator new

本文介绍了C++中操作符new的使用方法,包括默认行为及如何通过重载自定义分配行为。此外,还详细解释了placement new的作用及其与普通new的区别。

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

操作符new的用法就很常见 SomeClasss* psc = new SomeClasss(...)
实际上做的工作是:

1. 调用 void * operator new(size_t size);

即 psc = operator new(sizeof(SomeClasss));

2. 初始化

psc->SomeClasss(...)

但是你可以自己定义operator new的行为. //??原来的行为是在Heap中分配内存空间,自己也可以这么做吗?

More effecitive C++中说:

 你能增加额外的参数重载函数operator new,但是第一个参数类型必须是size_t。(有关operator new更多的信息参见Effective C++ 条款8至条款10。)

当然你可以直接使用operator new函数

操作符operator new将返回一个指针,指向一块足够容纳一个string类型对象的内存。

 


placement new的工作和operator new差不多,唯一的差别是placement new没有分配内存

Widget * constructWidgetInBuffer(void *buffer,

                                 int widgetSize)

{

  return new (buffer) Widget(widgetSize);

}

因为buffer已经指出了分配的内存所在
<think>嗯,用户问的是placement newoperator newC++中的区别。我需要先回忆一下这两个概念的不同之处。根据提供的引用资料,operator new有三种形式:普通的抛出异常的版本,nothrow版本,还有placement new。而placement new其实是operator new的第三种形式,也就是带有额外参数的版本。用户可能对这两者的关系区别不太清楚。 首先,我需要明确operator new的基本作用。operator newC++中用于动态分配内存的函数,通常与new表达式相关。当使用new关键字创建一个对象时,编译器会先调用operator new来分配内存,然后调用构造函数初始化对象。例如,引用[1]提到operator new有三种形式,其中第三种是placement new,它不分配内存,而是在已分配的内存上构造对象。 接下来,placement new的具体用途是什么。根据引用[2],placement new允许在已存在的内存地址上构造对象。比如,用户可能有一块预先分配好的内存,想要在这个位置创建对象,这时就可以用placement new。例如,代码中的new (&x) X(5)就是在x的地址上构造一个新的X对象,覆盖原有的值。这跟普通的operator new不同,普通的operator new会分配新的内存。 用户可能混淆的是operator newnew操作符的区别。引用[3]提到,new操作符(new operator)是C++的关键字,它执行两个步骤:调用operator new分配内存,然后调用构造函数。而operator new仅仅负责内存分配,可以被重载。placement new则是operator new的一个特殊重载版本,它接受额外的参数,比如指针,来指定内存位置。 另外,用户可能关心如何释放placement new分配的内存。由于placement new并不分配内存,只是构造对象,所以不需要调用delete来释放内存。但需要显式调用对象的析构函数,然后根据需要处理原始内存,比如如果是栈上的内存,不需要释放,如果是手动管理的堆内存,可能需要其他方式释放。引用[2]也提到了这一点,指出需要手动调用析构函数。 还需要注意,operator new可以被重载,但根据引用[3],每个重载的operator new必须有一个用户定义类型的参数,这可能影响用户自定义内存管理的方式。 总结一下,区别主要在于功能使用场景:operator new负责分配内存,placement new是它的一个版本,用于在指定内存构造对象。而new操作符则是组合了内存分配构造的过程。需要明确每个步骤的责任,以及如何正确管理内存对象生命周期。</think>### Placement newoperator new的区别解析 #### 一、核心概念定义 1. **operator new** operator newC++中负责内存分配的基础函数,有三种形式: ```cpp void* operator new(size_t size); // 基本形式(可能抛出bad_alloc) void* operator new(size_t size, const std::nothrow_t&) noexcept; // 不抛出版本 void* operator new(size_t size, void* ptr) noexcept; // placement形式(不分配内存)[^1] ``` 它只负责内存分配,不涉及对象构造。 2. **placement new** 是operator new的第三种特殊形式,特点: - 在**已分配好的内存地址**上构造对象 - 不进行实际内存分配 - 语法形式:`new (address) Type(args)` #### 二、关键差异对比 | 特性 | operator new | placement new | |---------------------|--------------------|---------------------| | 内存分配 | ✅ 分配新内存 | ❌ 使用现有内存 | | 构造函数调用 | ❌ 仅分配内存 | ✅ 触发构造函数 | | 异常处理 | 可能抛出bad_alloc | 不抛出异常 | | 典型应用场景 | 常规对象创建 | 内存池/对象复用 | | 内存释放方式 | delete操作符 | 需手动调用析构函数 | #### 三、工作流程示例 ```cpp #include <new> class MyClass { public: MyClass(int x) { /* 构造函数 */ } ~MyClass() { /* 析构函数 */ } }; // 使用placement new void demo() { char buffer[sizeof(MyClass)]; // 预分配内存 MyClass* obj = new (buffer) MyClass(10); // placement new构造 obj->~MyClass(); // 必须显式调用析构函数 } ``` #### 四、注意事项 1. 内存生命周期管理需手动控制[^2] 2. 不要对placement new返回的指针使用delete 3. 内存对齐要求需自行保证 4. 与内存池、自定义分配器配合使用时效率最佳 #### 五、典型应用场景 1. 嵌入式系统内存管理 2. 高性能计算中的对象池 3. 自定义内存分配策略 4. 需要精确控制对象位置的特殊需求(如硬件寄存器映射)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值