【问题标题】:Preventing unsafe dereferencing of std::unique_ptr防止不安全地取消引用 std::unique_ptr
【发布时间】:2015-12-20 09:35:21
【问题描述】:

取自 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_ptrs 并且仅对左值unique_ptrs 有效的解引用有意义吗?
  2. 仍有有效的用例可以保持右值 unique_ptr 可取消引用?

像这样:

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

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

【问题讨论】:

  • 您的意思是 *f(); 而不是 f(); 吗?
  • 顺便说一句。 const&amp; 仍然允许隐式对象是右值
  • auto non_dangling = f() 怎么样来避免这个问题?真的是需要修复的指针吗?
  • 正确的规范应该没有 const 吗?我的要求有可能吗?
  • @BoPersson 问题更多是关于这是否可以避免,即使是愚蠢的。机器可执行。

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


【解决方案1】:

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

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

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

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

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

由于右值强烈希望被右值引用绑定,因此任何取消引用涉及unique_ptr 的右值表达式的尝试都会导致编译错误 - “使用已删除的函数”。

禁止 operator* 用于右值 unique_ptrs 并且仅对左值 unique_ptrs 有效的取消引用有意义吗?

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

仍然有有效的用例来保持右值 unique_ptr 可取消引用?

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

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


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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-23
    • 2013-05-21
    • 2013-05-05
    • 2019-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多