2009-03-07 13 views
43

Tôi có nhiều đối tượng boost::shared_ptr<MyClass> và tại một số thời điểm, tôi cố ý muốn delete một số trong số đó giải phóng bộ nhớ. (Tôi biết tại thời điểm đó tôi sẽ không bao giờ cần các đối tượng được chỉ định tới MyClass nữa.) Làm cách nào để tôi có thể thực hiện điều đó?Làm thế nào để cố ý xóa một tăng :: shared_ptr?

Tôi đoán bạn không thể chỉ gọi delete() bằng con trỏ thô mà tôi nhận được với get().

Tôi đã nhìn thấy một hàm get_deleter(shared_ptr<T> const & p) trong boost::shared_ptr, nhưng tôi không chắc chắn cách sử dụng nó và cũng có thể nói thử nghiệm ngay bên cạnh nó. (Tôi nghĩ rằng tôi có Tăng 1,38.)

Có thể chỉ cần gán một ô trống mới boost::shared_ptr cho biến? Điều đó sẽ vứt bỏ giá trị cũ và xóa nó.

+15

NOOOOO: Không gọi xóa sau cuộc gọi để nhận(). Con trỏ thông minh vẫn có một bản sao và sẽ gọi xóa khi nó giải phóng đối tượng. –

Trả lời

80

Bạn chỉ cần làm

ptr.reset(); 

Xem shared_ptr manual. Nó tương đương với

shared_ptr<T>().swap(ptr) 

Bạn gọi reset trên mọi con trỏ thông minh không nên tham chiếu đối tượng nữa. Cuối cùng như vậy reset (hoặc bất kỳ hành động nào khác làm cho số lượng tham chiếu giảm xuống 0, thực tế) sẽ khiến cho đối tượng được tự do bằng cách sử dụng trình gỡ rối tự động.

Có thể bạn quan tâm đến số Smart Pointer Programming Techniques. Nó có một mục khoảng delayed deallocation.

8

Toàn bộ các điểm boost::shared_ptr<T> là đối tượng pointee sẽ bị xóa chính xác tại thời điểm khi không có shared_ptr<T> s điểm mà tại đó - có nghĩa là, khi người cuối cùng shared_ptr<T> trỏ vào đối tượng này đi ra khỏi phạm vi hoặc được bố trí để trỏ đến một đối tượng khác. Vì vậy, tất cả những gì bạn phải làm để xóa một đối tượng là đảm bảo không có shared_ptr<T> s trỏ vào nó. Ví dụ. nếu bạn chỉ có một đơn shared_ptr<T> gọi là p chỉ vào một đối tượng hoặc để nó rơi ra khỏi phạm vi hoặc gọi p.reset() (tương đương với p = NULL cho một con trỏ đơn giản) hoặc gán nó để trỏ vào một thứ khác.

Nếu bạn có hai shared_ptr<T> s trỏ vào đối tượng, bạn sẽ cần phải chỉ định lại cả hai.

EDIT: Nhờ dehmann đã chỉ ra rằng p = NULL; không phải là mã thực sự có giá trị trong một shared_ptr<T> ... :)

+3

Âm thanh tốt, nhưng một điều: Bạn không thể viết p = NULL, bởi vì p là một shared_ptr, không phải là một con trỏ. – Frank

+1

Có, cho câu hỏi liên quan về cách sử dụng NULL khi sử dụng shared_ptrs, hãy xem http://stackoverflow.com/questions/621220/null-pointer-with-boostsharedptr/621249#621249 –

+1

@dehmann: Rất tiếc, bạn hoàn toàn phải ... –

4

Những gì bạn muốn làm là trở về tài liệu tham khảo yếu sử dụng boost::weak_ptr có thể được chuyển đổi sang một shared_ptr khi cần. Điều này có thể cho phép bạn kiểm soát tuổi thọ của đối tượng trong shared_ptr và những người muốn truy cập nó có thể giữ lại weak_ptr và cố gắng chuyển đổi thành shared_ptr. Nếu chuyển đổi đó không thành công, thì chúng có thể truy vấn lại và đưa đối tượng trở lại bộ nhớ.

9

Nếu bạn muốn có thể cố tình xóa các đối tượng (tôi luôn làm tất cả) thì bạn phải sử dụng quyền sở hữu duy nhất. Bạn đã bị thu hút vào việc sử dụng shared_ptr khi nó không phù hợp với thiết kế của bạn.