2010-05-17 18 views

Trả lời

16

A weak_ptr giữ tham chiếu không sở hữu, do đó đối tượng mà nó tham chiếu có thể không tồn tại nữa. Sẽ rất nguy hiểm khi sử dụng con trỏ thô được giữ bởi weak_ptr.

Cách tiếp cận đúng là quảng bá số weak_ptr đến shared_ptr bằng cách sử dụng weak_ptr::lock() và lấy con trỏ từ đó.

Boost weak_ptr documentation giải thích lý do tại sao sẽ không an toàn để cung cấp chức năng get() như một phần của weak_ptr và có các ví dụ về mã có thể gây ra sự cố.

+0

Đối với vấn đề đó, bạn có thể được để lại bằng một con trỏ lơ lửng nếu bạn nhận được một con trỏ thô cho 'shared_ptr' bị hủy sau đó ... trong trường hợp Đa luồng, bạn thậm chí có thể được để lại với một con trỏ lơ lửng trong khi chạy mã 'if (! weak.expired()) weak-> run();' như đối tượng được trỏ tới có thể bị hủy giữa phép thử và thực thi phương thức (tôi cho rằng chính phương thức đó được đồng bộ hóa chính xác) ... –

+3

@Matthieu: tất nhiên bạn * có thể *, giống như bạn có thể được để lại với một con trỏ lơ lửng nếu bạn rõ ràng 'xóa' một đối tượng nhưng giữ một con trỏ đến nó. Điểm cần phải thúc đẩy 'weak_ptr' thành' shared_ptr' là nó khuyến khích bạn sử dụng con trỏ thô một cách chính xác, theo các quy tắc mà bạn thường sử dụng cho 'shared_ptr :: get'. Sẽ không có cách nào tương đương với việc sử dụng một con trỏ thô thu được trực tiếp từ 'weak_ptr'. –

2

Trước tiên, bạn cần lấy được shared_ptr từ weak_ptr trước khi giữ con trỏ thô.

Bạn có thể gọi lock để có được những shared_ptr, hoặc các nhà xây dựng shared_ptr:

boost::weak_ptr<int> example; 
... 

int* raw = boost::shared_ptr<int>(example).get(); 
+8

Như đã viết, điều này không an toàn - bạn có thể bị bỏ lại bằng một con trỏ lơ lửng nếu đối tượng bị xóa khi 'shared_ptr' tạm thời bị hủy. Bạn nên giữ 'shared_ptr' cho miễn là bạn đang sử dụng con trỏ thô. –

3

Đây là một câu hỏi cũ và câu trả lời được chấp nhận là tốt, vì vậy tôi ngần ngại gửi câu trả lời khác, nhưng có một điều mà dường như thiếu là một tốt thành ngữ sử dụng ví dụ:

boost::weak_ptr<T> weak_example; 
... 
if (boost::shared_ptr<T> example = weak_example.lock()) 
{ 
    // do something with example; it's safe to use example.get() to get the 
    // raw pointer, *only if* it's only used within this scope, not cached. 
} 
else 
{ 
    // do something sensible (often nothing) if the object's already destroyed 
} 

một lợi thế quan trọng của thành ngữ này là con trỏ mạnh có phạm vi đến if-đúng khối, giúp ngăn chặn vô tình sử dụng một tham chiếu không khởi tạo, hoặc giữ một tham chiếu mạnh mẽ quanh lâu er hơn là thực sự cần thiết.

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