C++ 布置new 布局new placement new

C++ 布置new 布局new placement new

new操作符(operator new)的语法

new操作符(operator new), 在头文件#include <new> 定义。

主要包括以下几类:

  1. 可替换的分配函数 void* operator new ( std::size_t count );,如T* p1 = new T;
  2. 可替换的不抛出分配函数 void* operator new ( std::size_t count, const std::nothrow_t& tag );
  3. 不分配布置分配函数 void* operator new ( std::size_t count, void* ptr );,如T* p2 = new (p1)T
  4. 用户定义布置分配函数 void* operator new ( std::size_t count, 用户定义实参... );
  5. 类特定分配函数 void* T::operator new ( std::size_t count );
  6. 类特定布置分配函数 void* T::operator new ( std::size_t count, 用户定义实参... );
参数含义
count要分配的字节数
ptr指向要初始化的对象所在的内存区域的指针
tag用于选择不抛出重载的消歧义标签

示例代码

#include <new>
#include <stdio.h>

class T {
public:
  T() { printf("T::T()\n"); };
  T(int n) { printf("T::T(int n)\n"); };
  ~T() { printf("T::~T()\n"); };
};

int main() {
  T *p1 = new T; // 

  p1->~T();
  T *p2 = new (p1) T(2); // do not delete p2

  delete p1;
  p1 = nullptr;

  return 0;
}

执行结果

T::T()
T::~T()
T::T(int n)
T::~T()

布置new (placement new)

普通new是在堆(heap)上分配空间。

布置new(placement new)不申请空间,而是在已分配的空间上创建对象。

new/delete的过程

// new
void *ptr = malloc(sizeof(T)*1); // malloc分配空间
T* t = new(ptr)T; // 已分配空间上创建对象 - 布置new(placement new)

// delete
t->~T(); // 析构
free(ptr); // free释放空间

布置new(placement new)的注意事项

  1. 布置new(placement new)所使用的的空间,可以是堆(heap)空间,也可以是栈(stack)空间
  2. 由于布置new(placement new)并没有申请空间,在已分配空间上调用构造函数,因此需要显示调用析构函数
  3. 由于布置new(placement new)并没有申请空间,因此delete应该由原来分配空间的地方进行调用

License

License under CC BY-NC-ND 4.0: 署名-非商业使用-禁止演绎


Reference:

  1. operator new - cppreference.com
  2. new expression - cppreference.com
  3. Union declaration - cppreference.com

http://www.niftyadmin.cn/n/4984311.html

相关文章

QT基础教程之六布局管理器和常用控件

QT基础教程之六布局管理器和常用控件 布局管理器 所谓 GUI 界面&#xff0c;归根结底&#xff0c;就是一堆组件的叠加。我们创建一个窗口&#xff0c;把按钮放上面&#xff0c;把图标放上面&#xff0c;这样就成了一个界面。在放置时&#xff0c;组件的位置尤其重要。我们必须…

常用框架分析(7)-Flutter

框架分析&#xff08;7&#xff09;-Flutter 专栏介绍Flutter核心思想Flutter的特点快速开发跨平台高性能美观的用户界面 Flutter的架构框架层引擎层平台层 开发过程使用Dart语言编写代码编译成原生代码热重载工具和插件 优缺点优点跨平台开发高性能美观的用户界面热重载强大的…

成集云 | 抖店客户静默下单催付数据同步钉钉 | 解决方案

源系统成集云目标系统 方案介绍 随着各品牌全渠道铺货&#xff0c;主播在平台上直播时客户下了订单后不能及时付款&#xff0c;第一时间客户收不到提醒&#xff0c;不仅造成了客户付款率下降&#xff0c;更大量消耗了企业的人力成本和经济。而成集云与钉钉深度合作&#xff0…

【LeetCode】28 . 找出字符串中第一个匹配项的下标

28 . 找出字符串中第一个匹配项的下标&#xff08;简单&#xff09; 方法&#xff1a;双指针法 思路 使用 find 函数枚举原串 ss 中的每个字符作为「发起点」&#xff0c;每次从原串的「发起点」和匹配串的「首位」开始尝试匹配&#xff1a; 匹配成功&#xff1a;返回本次匹配…

如何解决Memcached缓存击穿和雪崩问题

原文 Memcached是一种快速、高性能的分布式内存对象缓存系统&#xff0c;广泛应用于Web应用的缓存中。然而&#xff0c;Memcached也存在一些常见的问题&#xff0c;如缓存击穿和缓存雪崩。本文将介绍什么是缓存击穿和缓存雪崩&#xff0c;并提供一些解决这些问题的方法&#x…

兴业数金一面凉经

1.简单介绍一下自己 2.实际java使用时间长短 3.spring boot怎么学习的 学java都学了哪些东西 4.Spring boot全局异常处理怎么做&#xff0c;有几种方式 5.鉴权和登录都怎么实现 是用gateway吗 6.前端用的什么技术栈 前端发送过来一个请求经过哪些流程 7.项目里挑选一个模…

etcd读写请求的执行过程

etcd读请求如何执行 首先&#xff0c;etcdctl 会对命令中的参数进行解析。在解析完请求中的参数后&#xff0c;etcdctl 会创建一个 clientv3 库对象通过gRPC API来访问 etcd server。对应流程一。 然后通过负载均衡算法选择一个etcd server节点&#xff0c;然后调用 etcd ser…

Ansible学习笔记5

copy模块&#xff1a;&#xff08;重点&#xff09; copy模块用于对文件的远程拷贝&#xff08;如把本地的文件拷贝到远程主机上。&#xff09; 在master的主机上准备一个文件&#xff0c;拷贝文件到group1的所有主机上。 这个用的频率非常高&#xff0c;非常有用的一个模块…