Trong C++ dự thảo tiêu chuẩn (N3485), nó khẳng định như sau:Tại sao std :: operator_ptr operator * throw và operator-> không ném?
20.7.1.2.4 quan sát unique_ptr [unique.ptr.single.observers]
typename add_lvalue_reference<T>::type operator*() const;
1 Requires: get() != nullptr.
2 Returns: *get().
pointer operator->() const noexcept;
3 Requires: get() != nullptr.
4 Returns: get().
5 Note: use typically requires that T be a complete type.
Bạn có thể thấy rằng operator*
(dereference) không được chỉ định là noexcept
, có thể do nó có thể gây ra một segfault, nhưng sau đó operator->
trên cùng một đối tượng được chỉ định là noexcept
. Các yêu cầu cho cả hai đều giống nhau, tuy nhiên có một sự khác biệt trong đặc tả ngoại lệ.
Tôi nhận thấy họ có các loại trả về khác nhau, một trả về một con trỏ và một tham chiếu khác. Có phải đó là nói rằng operator->
không thực sự dereference bất cứ điều gì?
Thực tế của vấn đề là sử dụng operator->
trên một con trỏ thuộc bất kỳ loại nào là NULL, sẽ segfault (là UB). Tại sao sau đó, một trong số các giá trị này được chỉ định là noexcept
và một số khác thì không?
Tôi chắc chắn tôi đã bỏ qua điều gì đó.
EDIT:
Nhìn vào std::shared_ptr
chúng tôi có điều này:
20.7.2.2.5 shared_ptr quan sát [util.smartptr.shared.obs]
T& operator*() const noexcept;
T* operator->() const noexcept;
Đó là không giống nhau ? Điều đó có liên quan gì đến các ngữ nghĩa quyền sở hữu khác nhau không?
"Có phải điều đó nói rằng toán tử-> thực sự không coi trọng bất cứ điều gì?" Có, đó là nó –
Có lẽ nó cho phép triển khai để ném vào một con trỏ null dereference nếu họ chọn. – Dan