c++ - 是否可以重新分配 std::unique_ptr 以使其旧值在构造新值之前*被销毁?
问题描述
我有兴趣将旧的个人项目更新为现代 C++。我很欣赏 RAII 如何简化清理:与其在函数中的每个返回点之前创建一个new
对象并记住它,不如将它适当地销毁。但是在比较生成的程序集时我有一个挑剔。delete
make_unique
假设有一个类方法将其unique_ptr
成员之一替换为新值:
// std::unique_ptr<int> MyClass::m_foo;
void MyClass::refresh_foo(int x) {
m_foo = std::make_unique<int>(x * 3 + 5);
}
这将创建一个new
int
,将其分配给m_foo
,然后delete
是 的旧值m_foo
。但这与旧行为不太一样,旧行为可能delete
是旧值,然后创建new
一个并将其分配给m_foo
:
// int *MyClass::m_foo;
void MyClass::refresh_foo(int x) {
delete m_foo;
m_foo = new int(x * 3 + 5);
}
从Compiler Explorer中,gcc、clang 和 MSVC 为旧方式生成的代码都比新方式少。我理解为什么会这样,因为这是评估所有表达式的顺序;p = q;
必须先建造q
。当然,在和行m_foo
之间有一个无效值。但是有没有一种方法可以让我破坏它的旧值,然后在一个表达式中创建一个新的?一个“ ”?似乎在处理大型对象时会有所帮助,因此它们中的两个不会不必要地共存。delete
new
unique_ptr
replace_unique
编辑:为了清楚起见,我只是int
在这里用作一个简单的例子。我的实际用例是我自己的类或库中的类。与m_foo.reset(new int(x * 3 + 5));
旧的做事方式相比,自然有同样的问题,因为它也必须new
int
在分配它之前构造 the 和delet
ing 前一个。
解决方案
您可以根据unique_ptr::reset()
需要确定性地销毁当前持有的对象。unique_ptr
用一个指针更新nullptr
它,然后用一个新的对象指针更新它,例如:
// std::unique_ptr<int> MyClass::m_foo;
void MyClass::refresh_foo(int x) {
m_foo.reset(); // <- int is destroyed here
m_foo = std::make_unique<int>(x * 3 + 5);
}
推荐阅读
- coin-or-cbc - 如何检查 CBC 中模型的解决方案是否可行
- idris - 伊德里斯的 RecursiveDo?(在 do 表示法中使用定义之前的值)
- python - 找不到文件:Python Pytorch 上的 archive/constants.pkl
- reactjs - React.createRef() 创建了哪种类型的引用?
- php - 相同的值在每个重复多次
- python - reading files in python using minimum lines of code
- reactjs - 使用 .env 文件值时发现奇怪
- arrays - if 和 else 语句的问题
- c - 如何确定指针是否在rodata中
- python - RuntimeError: Found dtype Long but expected Float: 使用标准时