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

潍坊行业网站检察机门户网站建设自查报告

潍坊行业网站,检察机门户网站建设自查报告,唐山市城市建设规划局网站,濉溪县最新通告今天Effective C 条款52:写了placement new也要写placement delete核心思想:当你重载一个带有额外参数的operator new(即“placement new”)时,必须同时重载带有完全相同额外参数的operator delete。否则,当对象…

Effective C++ 条款52:写了placement new也要写placement delete


核心思想当你重载一个带有额外参数的operator new(即“placement new”)时,必须同时重载带有完全相同额外参数的operator delete。否则,当对象的构造函数在placement new分配的内存上抛出异常时,会发生微妙而严重的内存泄漏。同时,要注意避免无意中掩盖全局的正常版本。

⚠️ 1. 问题的根源:构造函数异常

1.1 C++的内存分配与构造流程

  1. operator new 分配原始内存
  2. 在该内存上调用构造函数
  3. 如果步骤2的构造函数抛出异常,运行时系统必须能够自动释放在步骤1中分配的内存,以避免内存泄漏。

1.2 运行时系统的职责
当构造函数抛出异常,运行时系统需要找到与调用operator new签名完全相同operator delete来释放内存。如果找不到,则什么也不做,导致内存泄漏。


🚨 2. placement new/delete 的匹配规则

2.1 标准placement new
最常用的placement new是接收一个void*指针参数,用于在指定地址构造对象。

// 标准库提供的placement new
void* operator new(std::size_t, void* pMemory) noexcept; 
// 对应的placement delete
void operator delete(void* pMemory, void* pLocation) noexcept; 

2.2 自定义placement new
你可以定义接收任意额外参数的operator new

class Widget {
public:// 自定义的placement new(额外带一个int参数)static void* operator new(std::size_t size, int extraParam) {std::cout << "Custom placement new called with: " << extraParam << std::endl;return ::operator new(size); // 这里为了简单,仍使用全局new}// ⚠️ 必须提供对应的placement delete!// 参数列表:(size_t) + 与placement new完全相同的额外参数列表(int)static void operator delete(void* pMemory, int extraParam) noexcept {std::cout << "Custom placement delete called with: " << extraParam << std::endl;::operator delete(pMemory);}// ... 通常的operator delete也不能少static void operator delete(void* pMemory) noexcept;
};

使用示例与潜在问题

try {// 调用自定义的placement newWidget* pw = new (100) Widget; // 传递额外参数100// ... 如果Widget构造函数在此处抛出异常...// 运行时系统会自动调用 operator delete(pw, 100)
} catch (...) {// 如果没有定义 operator delete(void*, int),内存将在此泄漏
}

⚖️ 3. 避免名称隐藏问题

3.1 默认的名称隐藏(Name Hiding)
在类中声明任何operator new(包括placement版本)都会隐藏全局的、标准的operator new。这意味着new Widget会编译失败,因为找不到标准的operator new(size_t)

3.2 解决方案:提供标准版本并using基类版本
为了同时使用自定义placement new和标准new,必须在类中同时声明它们,并使用using引入基类的operator new以确保继承链正常工作。

class StandardNewDeleteBase {
public:// 提供标准new/delete的入口static void* operator new(std::size_t size) {return ::operator new(size);}static void operator delete(void* pMemory) noexcept {::operator delete(pMemory);}// ... 可补充new[]和delete[]
};class Widget : public StandardNewDeleteBase {
public:using StandardNewDeleteBase::operator new;using StandardNewDeleteBase::operator delete;// 自定义placement newstatic void* operator new(std::size_t size, int extraParam) {// ... 自定义实现return ::operator new(size);}// 对应的placement deletestatic void operator delete(void* pMemory, int extraParam) noexcept {// ... 自定义实现::operator delete(pMemory);}
};// 现在以下调用都是合法的:
Widget* pw1 = new Widget;           // 正确,调用了被using引入的标准new
Widget* pw2 = new (100) Widget;     // 正确,调用了自定义的placement new

💡 关键设计原则

  1. 成对实现
    每一个自定义的placement operator new(即任何非标准的、带有额外参数的new)都必须有一个参数列表完全匹配的placement operator delete伴随左右。这是防止构造函数异常导致内存泄漏的唯一安全网。
  2. 理解调用时机
    placement operator delete 只有在与之匹配的placement operator new成功分配内存,但后续的对象构造函数抛出异常时,才会被运行时系统自动调用。如果你正常地delete一个对象,即使它是用placement new创建的,被调用的也永远是普通的operator delete(void*)
  3. 管理名称空间
    在类内部重载operator new/delete会隐藏全局版本。务必使用using ::operator new;using ::operator delete;(或使用如上面示例中的基类技巧)来确保所有需要的版本都可见,保持代码的灵活性。

进阶提示:大小感知的placement delete (C++14+)
现代C++允许placement delete也接受大小参数,这在实现自定义内存池时非常有用,可以优化释放操作。

class Widget {// ...// 大小感知的placement delete (更优)static void operator delete(void* pMemory, std::size_t size, int extraParam) noexcept {std::cout << "Sized placement delete. Size: " << size << ", Param: " << extraParam << std::endl;::operator delete(pMemory);}
};

编译器会优先选择最匹配的版本。提供大小感知的版本通常是最佳实践。

总结
placement new和placement delete是“成对出现”的生死之交。定义任何形式的placement operator new(即带有额外参数的new)时,都必须毫不例外地定义与之精确匹配的placement operator delete。这是确保在对象构造失败时系统能自动清理内存、避免资源泄漏的黄金法则。此外,要小心类内重载带来的名称隐藏问题,通过使用using声明或继承体系来确保标准的new/delete版本依然可用。遵守此条款,你才能安全地利用placement new的强大功能进行底层内存管理。

http://www.dtcms.com/a/402868.html

相关文章:

  • 网站关键词库怎么做分享网站友情链接
  • 家具能在什么网站上做免费咨询在线医生
  • 河北建设厅网站登陆怎么找附件黄岛网站建设哪家权威
  • 建设通网站是做什么的外链网站有哪些
  • 自然堂网站建设策划书电脑和手机同步编辑wordpress
  • 请人建设网站需要注意什么wordpress 管理员权限设置
  • 男女做暖网站国外图片网站源码
  • 工程项目网站wordpress模板製作
  • 做网站需要跟客户了解什么软件家在深圳 歌曲
  • 关于网站建设的调研报告企业seo解决方案
  • 网站开发网络公司兼职百度怎么免费推广自己的产品
  • 网站策划书案例展示游戏网站规划方案
  • 如何在年报网站上做遗失公告樱花16q808a
  • 郴州网站建设解决方案网站 免费 托管运营
  • 网站关键字没有排名素材网站 国外
  • 游戏自助充值网站怎么做网站开发目标开题报告
  • 宁波网站怎么建设wordpress访问过的页码不变色
  • 三门峡做网站的公司建设网站南沙
  • 网站怎样做301购物网站建站系统
  • 如何自建网站?贵州最近爆发的传染病
  • 新郑市住房建设局网站网站建设Skype打不开
  • 专业网站设计制作优化排名ui设计30岁后的出路
  • 做儿童方面的网站wordpress大前端dux5.2
  • 企业网站设计策划案信用网站标准化建设模块都有哪些
  • 有关网站建设有那些功能wordpress爆破软件
  • 做网站的有哪些公司网站开发需不需要考研
  • 自已建网站微信登录网站logo设计教程
  • 赤峰网站建设建站公司企业门户网站运营推广
  • 如何用WordPress建小说站wordpress怎么做301重定向
  • 建站技术服务新建的网站打不开