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周年了!

相关推荐
时见先生2 小时前
Python库和conda搭建虚拟环境
开发语言·人工智能·python·自然语言处理·conda
a努力。2 小时前
国家电网Java面试被问:混沌工程在分布式系统中的应用
java·开发语言·数据库·git·mysql·面试·职场和发展
Yvonne爱编码2 小时前
Java 四大内部类全解析:从设计本质到实战应用
java·开发语言·python
wqwqweee2 小时前
Flutter for OpenHarmony 看书管理记录App实战:搜索功能实现
开发语言·javascript·python·flutter·harmonyos
yongui478343 小时前
基于MATLAB的NALM锁模光纤激光器仿真实现
开发语言·matlab
毕设源码-郭学长3 小时前
【开题答辩全过程】以 基于springboot 的豪华婚车租赁系统的设计与实现为例,包含答辩的问题和答案
java·spring boot·后端
-To be number.wan3 小时前
Python数据分析:numpy数值计算基础
开发语言·python·数据分析
imX2G3 小时前
爆破小游戏2.0
c++
Cx330❀4 小时前
【优选算法必刷100题】第41-42题(模拟):Z 字形变换,外观数列
c++·算法
Cx330❀4 小时前
【优选算法必刷100题】第038题(位运算):消失的两个数字
开发语言·c++·算法·leetcode·面试