简体   繁体   English

防止std :: unique_ptr的不安全解除引用

[英]Preventing unsafe dereferencing of std::unique_ptr

Taken from a slide at cppcon2015: 摘自cppcon2015的幻灯片:

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

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

//BOOM!!!
use(dangling);

My question is: with rvalue references for *this, can this be solved? 我的问题是:对于* this的rvalue引用,这可以解决吗?

I see in the spec in cppreference: 我在cppreference的spec中看到:

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

Question: 题:

  1. Would it make sense to disallow operator* for rvalue unique_ptr s and only have dereference valid for lvalue unique_ptr s? 是否允许operator*为rvalue unique_ptr而且只有对于左值unique_ptr s有效的解除引用才有意义吗?
  2. There are still valid use cases to keep the rvalue unique_ptr dereferenceable? 还有一些有效的用例可以保持rvalue unique_ptr解除引用吗?

Like this: 像这样:

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

NOTE: I am not sure of the syntax or correctness, I have no experience with rvalue references for *this. 注意:我不确定语法或正确性,我对* this的rvalue引用没有经验。

My question is: with rvalue references for *this , can this be solved? 我的问题是:对于*this rvalue引用,这可以解决吗?

Technically yes. 技术上是的。 One solution would be to introduce an additional (deleted) overload for rvalues: 一种解决方案是为rvalues引入一个额外的(删除的)重载:

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

and to modify the existing one by means of adding a ref-qualifier: 并通过添加ref-qualifier来修改现有的:

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

Since rvalues strongly prefer to be bound by an rvalue reference, any attempt to dereference an rvalue expression involving a unique_ptr would result in a compile error - "use of deleted function". 由于rvalues强烈倾向于被rvalue引用绑定,因此任何尝试取消引用涉及unique_ptr的rvalue表达式都会导致编译错误 - “使用已删除的函数”。

Would it make sense to disallow operator* for rvalue unique_ptrs and only have dereference valid for lvalue unique_ptrs ? 为rvalue unique_ptrs禁用operator*并且只对lvalue unique_ptrs有效取消引用是否有意义?

Not always. 不总是。 And because of that I doubt the library should impose additional constraints on the unique_ptr specification, only to prevent a possible misuse. 因此,我怀疑库应该对unique_ptr规范施加额外的限制,只是为了防止可能的误用。

There are still valid use cases to keep the rvalue unique_ptr dereferenceable? 还有一些有效的用例可以保持rvalue unique_ptr解除引用吗?

The lifetime of a temporary ends at the end of a full expression that the temporary is part of. 临时的生命周期在临时属于完整表达式的末尾结束。 This means that the object obtained from dereferencing a unique_ptr is valid as long as the associated unique_ptr is alive, so the below use-cases are valid, and wouldn't be possible if operator* was disabled for rvalues: 这意味着只要关联的unique_ptr处于活动状态,从解除引用unique_ptr获得的对象就是有效的,因此下面的用例是有效的,如果对rvalues禁用operator*则不可能:

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


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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM