2015-09-23 14 views
5

Taken từ một slide tại cppcon2015:Ngăn cản dereferencing không an toàn của std :: unique_ptr

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

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

//BOOM!!! 
use(dangling); 

Câu hỏi của tôi là: với sự tham khảo rvalue cho * này, có thể này được giải quyết?

tôi thấy trong spec trong cppreference:

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

Câu hỏi:

  1. Nó có ý nghĩa để không cho phép operator* cho rvalue unique_ptr s và chỉ có giá trị trong dereference vế trái unique_ptr s?
  2. Vẫn còn trường hợp sử dụng hợp lệ để giữ giá trị unique_ptr không thể chấp nhận được?

Như thế này:

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

LƯU Ý: Tôi không chắc chắn của các cú pháp hoặc đúng đắn, tôi không có kinh nghiệm với sự tham khảo rvalue cho * này.

+3

Did bạn có nghĩa là '* f();' thay vì 'f();'? –

+0

btw. 'const &' sẽ vẫn cho phép đối tượng tiềm ẩn là một giá trị –

+1

Còn 'auto non_dangling = f()' để tránh vấn đề thì sao? Nó thực sự là con trỏ cần được sửa? –

Trả lời

3

Câu hỏi của tôi là: với tham chiếu rvalue cho *this, điều này có thể được giải quyết không?

Về mặt kỹ thuật có. Một giải pháp sẽ được giới thiệu một (xóa) quá tải bổ sung cho rvalues:

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

và sửa đổi một trong những hiện bằng phương pháp thêm một ref-vòng loại:

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

Kể từ rvalues ​​mạnh thích được bị ràng buộc bởi một tham chiếu rvalue, bất kỳ cố gắng để dereference một biểu thức rvalue liên quan đến một unique_ptr sẽ dẫn đến một lỗi biên dịch - "sử dụng chức năng đã xóa".

Nó có ý nghĩa để không cho phép operator* cho rvalue unique_ptrs và chỉ có giá trị trong dereference vế trái unique_ptrs?

Không phải lúc nào. Và vì lý do đó, tôi nghi ngờ thư viện nên áp đặt các ràng buộc bổ sung vào đặc tả unique_ptr, chỉ để ngăn chặn việc lạm dụng có thể xảy ra.

Vẫn còn trường hợp sử dụng hợp lệ để giữ giá trị unique_ptr không thể chấp nhận được?

Vòng đời tạm thời ở cuối biểu thức đầy đủ rằng tạm thời là một phần của.Điều này có nghĩa rằng đối tượng thu được từ dereferencing một unique_ptr là hợp lệ miễn là liên quan đến unique_ptr còn sống, vì vậy các trường hợp sử dụng dưới đây có giá trị, và sẽ không thể xảy ra nếu operator* đã bị vô hiệu hóa cho rvalues:

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


use(*f()); 
//  ^~~ unique_ptr is destroyed here 
Các vấn đề liên quan