C++与Rust那些事之跳过析构函数

C++与Rust那些事之跳过析构函数

在Rust中mem::forget用于防止对象的析构,跳过清理工作,从而让资源的释放交给其他机制管理。

例如:

go 复制代码
let file = File::open("foo.txt").unwrap();
mem::forget(file);

那么在C++中如何防止析构?即跳过析构函数呢?

本节将给出三种办法,完整代码示例也放于星球。

1. placement new

placement new可以让我们手动管理对象的构造和析构。如果不手动调用对象的析构函数,我们就可以跳过对象的析构,从而实现类似mem::forget的效果。

例如:

go 复制代码
alignas(Foo) std::byte storage[sizeof(Foo)];  // 分配对齐的原始内存块
Foo* pfoo = new (storage) Foo();  // 在这块内存上构造Foo对象

在上面的代码中,placement new创建了对象pfoo,但我们不调用析构函数,这样可以跳过对象的清理逻辑。

2. 使用智能指针的自定义删除器

另一种实现类似功能的方法是通过自定义智能指针的删除器,防止对象被销毁。我们可以定义一个不执行任何操作的删除器,从而避免析构函数的调用。

go 复制代码
std::unique_ptr<Foo, NoOpDeleter> pfoo(new Foo(), NoOpDeleter{});

使用自定义的删除器NoOpDeleter,我们可以防止std::unique_ptr在离开作用域时调用析构函数,从而实现类似mem::forget的效果。

3.union

union的方案很神奇,大家知道原理吗?欢迎留言区一起讨论~

go 复制代码
template <class T>
union Wrapper {
  T value;
  ~Wrapper() {}
};

struct Foo {
  ~Foo() { std::cout << "dtor foo\n"; }
};

Wrapper<Foo> f; 
// f.value.~Foo);  必须手动调用

欢迎留言区讨论~

一起探索更多C++项目/知识~

往期推荐:

向量数据库milvus源码剖析之开篇

热度更新,手把手实现工业级线程池

玩转cpp小项目星球3周年了!

相关推荐
Reart10 分钟前
Leetcode 309.买卖股票的最佳时期含冷冻期(你也想成为股票高手吗o〃ω〃o,718)
后端
小小的木头人16 分钟前
Python 批量解析 Excel 经纬度,调用高德地图 API 获取中文地址
开发语言·python·excel
Reart25 分钟前
Leetcode 188.买卖股票的最佳时机4(718)
后端·算法
Reart40 分钟前
Leetcode 123.买卖股票的最佳时期3(内有随心谈,718)
后端·算法
只与明月听1 小时前
LangChain 学习-掌握LangChain Core API
前端·人工智能·后端
nzz_1712141 小时前
PHP程序员转型AI岗位指南:核心技能、北京就业市场与转型路径分析
开发语言·人工智能·php
无相求码1 小时前
数组越界为什么有时候不崩溃?VS2013 下栈上变量的幽灵布局解密
c语言·后端
Risehuxyc1 小时前
C# 将doc转换为docx
开发语言·c#·xhtml
是个西兰花2 小时前
Linux:深入解析Linux线程原理与实现
linux·运维·c++·线程·互斥锁
多加点辣也没关系2 小时前
JavaScript|第24章:事件循环与并发模型
开发语言·javascript·ecmascript