当前位置: 首页 > news >正文

new的几种形式

C++ 中的 new 操作符实际上有多种形式,根据使用方式和功能可分为如下几类:


✅ 一、基本形式

1. 普通单对象分配

MyClass* p = new MyClass();         // 默认构造
MyClass* p2 = new MyClass(123);     // 调用带参构造函数

2. 数组形式

MyClass* arr = new MyClass[10];     // 分配并构造 10 个默认构造的对象

必须配对使用 delete[],否则只析构第一个对象!


✅ 二、带 nothrow 的安全形式(避免异常)

MyClass* p = new(std::nothrow) MyClass();
if (!p) {// 分配失败,不抛异常,返回 nullptr
}

适用于资源有限、不能容忍异常的系统(如嵌入式设备)。


✅ 三、Placement new(定址构造)

已有内存上构造对象,常用于自定义内存池、共享内存等场景。

void* buffer = malloc(sizeof(MyClass));
MyClass* p = new (buffer) MyClass(123); // 定址构造

注意:

  • 不会分配内存,只调用构造函数;

  • 析构必须显式调用:p->~MyClass();


✅ 四、重载版本(类或全局)

你可以重载 operator new 来控制分配行为:

void* MyClass::operator new(std::size_t size) {std::cout << "custom new\n";return ::operator new(size);
}
void MyClass::operator delete(void* ptr) {std::cout << "custom delete\n";::operator delete(ptr);
}

还可以写成 全局重载版本,或接受额外参数用于调试/分区管理。


✅ 五、对齐版本(C++17 起)

struct alignas(64) AlignedClass {int data;
};AlignedClass* p = new AlignedClass();  // 自动 64 字节对齐

也可以自定义重载如下:

void* operator new(std::size_t size, std::align_val_t align);

✅ 六、数组 + Placement + 对齐的组合形式(不推荐混用)

可以组合使用,如:

void* mem = malloc(sizeof(MyClass) * 10);
MyClass* arr = new (mem) MyClass[10]; // 错误!数组不能用 placement new 这样构造!

new T[n]placement new 不兼容数组构造,要显式循环手动构造:

for (int i = 0; i < 10; ++i)new (static_cast<void*>(mem) + i * sizeof(MyClass)) MyClass();

🔁 全部形式简表

形式示例特点
普通 newnew MyClass(1)分配 + 构造
普通 new[]new MyClass[10]构造多个对象
nothrow newnew(std::nothrow) MyClass()分配失败返回 nullptr,不抛异常
Placement newnew (ptr) MyClass(1)在已有地址构造,不分配内存
自定义重载 operator newMyClass::operator new(...)控制分配策略
对齐 new(C++17)new (std::align_val_t(64)) MyClass()用于 SIMD / 硬件对齐需求
数组 + 对齐 new(复杂慎用)new (std::align_val_t(64)) MyClass[10]实现复杂,通常不推荐

✅ 总结一句话:

C++ 中 new 不只是“分配内存”,它是类型感知的对象创建机制,支持构造、析构、对齐和自定义行为,远比 malloc 灵活强大。

http://www.xdnf.cn/news/259129.html

相关文章:

  • 深入理解 C++ 变量:从基础到高级应用
  • 5月2日日记
  • (六——下)RestAPI 毛子(Http resilience/Refit/游标分页/异步大文件上传)
  • Linux-常用监控工具
  • 第 12 届蓝桥杯 C++ 青少组中 / 高级组省赛 2021 年 4 月 24 日真题(选择题)
  • Python Cookbook-6.16 用 Borg 惯用法来避免“单例”模式
  • Codeforces Round 1022 (Div. 2)(ABC)
  • GESP2024年6月认证C++八级( 第三部分编程题(1)最远点对)
  • 【愚公系列】《Manus极简入门》011-习惯养成教练:“习惯塑造师”
  • 【Java IO流】File类基础详解
  • 【IPMV】图像处理与机器视觉:Lec9 Laplace Blending 拉普拉斯混合
  • 常见工业汽车行业通讯接口一览表
  • vulkanscenegraph显示倾斜模型(6.2)-记录与提交
  • 数字智慧方案5877丨智慧交通项目方案(122页PPT)(文末有下载方式)
  • OpenLayers+WebGIS实时协作黑科技!多人同步标绘神器
  • 使用xlwings将两张顺序错乱的表格进行数据核对
  • 二叉搜索树的判断(双指针解决)
  • 深度残差网络ResNet
  • Controller层接收参数方式
  • 瑞萨 EZ-CUBE2 调试器
  • AI赋能新媒体运营:效率提升与能力突破实战指南
  • ZYNQ工业级串口方案:AXI UART 16550扩展RS-485实战(自动方向控制+Linux驱动)
  • AI大模型-微调和RAG方案选项
  • 友元函数和友元类
  • 【学习笔记】深入理解Java虚拟机学习笔记——第1章 走进Java
  • 4.1 模块概述
  • JavaScript基础-逻辑运算符
  • 【质量管理】现代TRIZ问题识别中的功能分析——组件分析
  • 网站怎样备份网站,备份网站数据的方法
  • 正弦波、方波、三角波和锯齿波信号发生器——Multisim电路仿真