2012-06-10 26 views
10

Mặc dù tôi hiểu tại sao không có operator== cho shared_ptrunique_ptr, tôi tự hỏi tại sao không có số nào cho shared_ptrweak_ptr. Đặc biệt là vì bạn có thể tạo một weak_ptr thông qua tham chiếu trên shared_ptr. Tôi giả định rằng 99% thời gian bạn muốn lhs.get() == rhs.get(). Bây giờ tôi sẽ tiếp tục và giới thiệu điều đó vào mã của tôi trừ khi ai đó có thể đặt tên cho tôi là một lý do chính đáng, tại sao người ta không nên làm một điều như vậy.Thiếu bình đẳng giữa shared_ptr và weak_ptr

+3

Nhưng 'weak_ptr' không có phương thức' get'. –

+0

Derp. Đã hiểu sai câu hỏi. –

Trả lời

15

weak_ptr doesn 'có phương thức get() vì bạn cần khóa rõ ràng weak_ptr trước khi bạn có thể truy cập con trỏ cơ bản. Làm cho điều này rõ ràng là một quyết định thiết kế có chủ ý. Nếu việc chuyển đổi được ngầm định thì sẽ rất dễ dàng để viết mã sẽ không an toàn nếu đối tượng cuối cùng bị hủy trong khi con trỏ cơ bản thu được từ số weak_ptr vẫn đang được kiểm tra.

This boost page có mô tả tốt về những cạm bẫy và lý do tại sao weak_ptr có giao diện hạn chế như vậy.

Nếu bạn cần so sánh nhanh, bạn có thể thực hiện shared == weak.lock(). Nếu so sánh là đúng thì bạn biết rằng weak vẫn phải hợp lệ khi bạn giữ riêng shared_ptr cho cùng một đối tượng. Không có đảm bảo như vậy nếu so sánh trả về sai.

+0

Gọi 'khóa' cho một phần lớn mã thực sự có ý nghĩa hơn. Quyết định thiết kế tốt. – abergmeier

4

Vì nó có chi phí.

A weak_ptr giống như người quan sát, không phải là con trỏ thực. Để thực hiện bất kỳ công việc nào với nó, trước tiên bạn cần lấy một shared_ptr từ nó bằng cách sử dụng phương thức lock() của nó.

Điều này có tác dụng giành quyền sở hữu, nhưng tốn kém như sao chép số shared_ptr thông thường (số lần tăng, v.v ...) nên không có gì là tầm thường.

Như vậy, bằng cách không cung cấp ==, bạn buộc phải lùi lại và thực sự kiểm tra xem bạn có thực sự cần điều này hay không.

+2

Tôi không chắc rằng so sánh bình đẳng cần phải quan tâm đến tính hợp lệ, và như vậy có thể được thực hiện với giá rẻ: hoặc 'weak_ptr' chỉ cùng một thực thể, trong trường hợp đó phải hợp lệ (hoặc 0), hoặc nó đề cập đến một thực thể khác, trong trường hợp này, chúng tôi không quan tâm liệu nó có hợp lệ hay không. –

+0

@KonradRudolph: có thể, có thể không. Nhưng vì việc lấy con trỏ sẽ không an toàn nói chung (vì bạn sẽ có con trỏ nhưng sẽ không thể truy cập con trỏ), bạn không thể lấy con trỏ từ 'weak_ptr' và buộc phải đi qua' shared_ptr'. Vì vậy ... –

+1

Không, lấy con trỏ là an toàn, miễn là nó được thực hiện * nội bộ *. –

Các vấn đề liên quan