c++ - 防止对 std::unique_ptr 的不安全取消引用

标签 c++ c++11 c++14 unique-ptr

摘自 cppcon2015 的幻灯片:

unique_ptr<A> f() {
   auto a = make_unique<A>();
   return a;
}

//Why does this even compile?
const A & dangling = *f(); 

//BOOM!!!
use(dangling);

我的问题是:对于 *this 的右值引用,这可以解决吗?

我在 cppreference 的规范中看到:

typename std::add_lvalue_reference<T>::type operator*() const;

问题:

  1. 不允许 operator* 用于右值 unique_ptr 并且只对左值 unique_ptr 取消引用有效吗?
  2. 仍然有有效的用例来保持右值 unique_ptr 可解引用?

像这样:

//Make sure it is an lvalue.
typename std::add_lvalue_reference<T>::type operator*() const &;

注意:我不确定语法或正确性,我对 *this 的右值引用没有经验。

最佳答案

My question is: with rvalue references for *this, can this be solved?

技术上是的。一种解决方案是为右值引入额外的(删除的)重载:

typename std::add_lvalue_reference<T>::type operator*() const&& = delete;
//                                                      ~~~~~~~~~~~~~~~^

并通过添加引用限定符来修改现有的:

typename std::add_lvalue_reference<T>::type operator*() const&;
//                                                         ~~^~~

由于右值强烈倾向于受右值引用的约束,任何对涉及 unique_ptr 的右值表达式的解引用都会导致编译错误 - “使用已删除的函数”。

Would it make sense to disallow operator* for rvalue unique_ptrs and only have dereference valid for lvalue unique_ptrs?

并不总是。因此,我怀疑图书馆是否应该对 unique_ptr 规范施加额外的限制,只是为了防止可能的误用。

There are still valid use cases to keep the rvalue unique_ptr dereferenceable?

临时对象的生命周期在临时对象所属的完整表达式结束时结束。这意味着只要关联的 unique_ptr 还存在,通过取消引用 unique_ptr 获得的对象就是有效的,因此下面的用例是有效的,并且是不可能的如果 operator* 为右值禁用:

(*f()).foo();
//          ^~~ unique_ptr is destroyed here


use(*f());
//       ^~~ unique_ptr is destroyed here

关于c++ - 防止对 std::unique_ptr 的不安全取消引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32733277/

相关文章:

c++ - 如何避免长 switch 语句? C++

c++ - 在 C++ 中使用模板参数进行矩阵乘法

c++ - 通过示例了解变量模板

c++14 - 在 CLion 中启用 C++14 支持?

c++ - 如何防止Windows显示 "Debug Error! abort() has been called"对话框?

c++ - 为什么 assert 定义为 (void)0?

c++ - xstring 中未定义的类型和未声明的标识符

c++11 - 歧义运算符<<选择

c++ - 为什么在这种情况下 cout 不会溢出?

c++ - map 中的循环迭代器