关于涉及唯一指针的安全操作
About safe operations involving unique pointers
考虑以下代码:
#include <memory>
struct Foo { std::unique_ptr<Foo> next; };
void f(Foo &foo) { foo = std::move(*foo.next); }
int main() {
Foo foo{};
foo.next = std::make_unique<Foo>();
foo.next->next = std::make_unique<Foo>();
f(foo);
}
通过执行foo = std::move(*foo.next);
,foo.next.next
被移动到foo.next
如果foo.next
作为第一步无效,则可以立即删除它所指向的对象。这将导致删除foo.next.next
,也就是我试图移动到foo.next
的对象
我很确定我的推理中遗漏了什么,但我搞不清楚出了什么问题
这是一个安全的操作吗?标准在哪里让我放心?
我认为这一切都非常安全。当您在foo
上调用f()
函数时,class Foo
的移动赋值运算符将调用std::unique_ptr<Foo>::operator=(std::unique_ptr<Foo>&&)
。现在,C++14标准,§20.8.1.2.3,逗号2,说:
效果:将所有权从
u
转移到*this
,就像调用reset(u.release())
然后调用get_deleter() = std::forward<D>(u.get_deleter())
一样。
在§20.8.1.2.5,逗号4,我们发现reset()
:的行为
效果:将
p
分配给存储的指针,然后如果存储指针的旧值old_p
不等于nullptr
,则调用get_deleter()(old_p)
。[注意:这些操作的顺序很重要,因为对get_deleter()
的调用可能会破坏*this
。--结束注释]
因此,我们可以争辩说,存储的指针将被替换,然后旧存储的指针将按此顺序被删除。因此,一切都很好,定义得很好。
此外,当您将输入到reset()
函数中时,*foo.next
对象将已经是release()
d,因此指向的对象不会被它破坏。
相关文章:
- 为表示一个或多个操作的C++函数的int参数寻找类型安全的替换
- 当其他线程正在编写线程安全时,我是否必须互斥读操作
- 哪些整数操作不安全
- 安全操作以清除C++中的空输入缓冲区
- 标准::atomic_应该如何...<std::shared_ptr>用于线程安全类的复制和移动操作?
- 关于涉及唯一指针的安全操作
- 此副本分配操作安全吗?
- 如何使C++endl操作器线程安全
- 关于 swap() 操作的异常安全 - 这有什么问题?
- 使用操作当前对象的线程是否安全
- 在C++中键入安全的物理操作
- 在 && 语句的后半部分进行无效操作是否安全?
- C++ 用于添加操作的线程安全
- 生产者和使用者函数,用于在操作手册中测试C++并发的线程安全堆栈示例
- 比较操作线程对 std::atomic 变量是安全的吗?
- 这样操作cv::Mat的内部缓冲区安全吗
- std::map上可能存在线程不安全操作
- xxx和bool在操作中的不安全混合仅在将值与TRUE进行比较时发出警告
- 是否有一种方法可以机械地识别在移出对象上哪些操作是安全的
- 使用memory_order_relax来加载原子变量是否安全,如果只有一个线程对该变量进行写操作