2009-11-20 30 views
31

scoped_ptr không thể sao chép được và đang bị xóa khỏi phạm vi. Vì vậy, nó là loại bị hạn chế shared_ptr. Vì vậy, có vẻ ngoài các trường hợp khi bạn thực sự cần phải hạn chế hoạt động sao chép shared_ptr là tốt hơn để sử dụng. Bởi vì đôi khi bạn không biết bạn cần phải tạo một bản sao của đối tượng của bạn hoặc không. Vì vậy, câu hỏi đặt ra là: bên cạnh các trường hợp được đề cập ở trên, chúng tôi có thể xem xét rằng shared_ptr là tốt hơn (hoặc được khuyến nghị) để sử dụng thay vì scoped_ptr. Có scoped_ptr hoạt động nhanh hơn nhiều từ shared_ptr hay không có lợi thế nào không?shared_ptr vs scoped_ptr

Cảm ơn!

Trả lời

64

shared_ptr nặng hơn scoped_ptr. Nó cần phân bổ và giải phóng một đối tượng đếm tham chiếu cũng như đối tượng được quản lý và để xử lý việc đếm tham chiếu thread-safe - trên một nền tảng mà tôi đã làm việc, đây là một chi phí đáng kể.

Lời khuyên của tôi (nói chung) là sử dụng đối tượng đơn giản nhất đáp ứng nhu cầu của bạn. Nếu bạn cần chia sẻ tính được tham chiếu, hãy sử dụng shared_ptr; nếu bạn chỉ cần xóa tự động sau khi bạn đã hoàn tất với một tham chiếu, hãy sử dụng scoped_ptr.

+16

Mike, tôi không thể đồng ý hơn. Tôi luôn khuyên mọi người nên bắt đầu với 'boost :: scoped_ptr'. Nếu bạn cần chuyển ngữ nghĩa quyền sở hữu (duy trì quyền sở hữu duy nhất) thì hãy "nâng cấp" lên 'std :: auto_ptr'. Nếu bạn chỉ cần chia sẻ quyền sở hữu thì bạn có sử dụng 'boost :: shared_ptr' hay không. Ngoài ra, thư viện 'Boost.ptr_container' là một lựa chọn tốt cho các thùng chứa tăng :: shared_ptr khi các phần tử không thực sự cần được chia sẻ. –

+2

Là một sang một bên: nếu bạn cần chia sẻ con trỏ, bạn có thể loại bỏ các phân bổ bổ sung bằng cách phân bổ các đối tượng bằng cách sử dụng 'make_shared' hoặc' allocate_shared' thay vì 'new'. –

+17

@David: Tôi hầu như đã đồng ý, nhưng tôi sẽ bỏ qua 'auto_ptr' hoàn toàn. Nó không thể được sử dụng một cách an toàn trong các thùng chứa tiêu chuẩn, vì vậy nó có khả năng gây ra một số bất ngờ khó chịu nếu bạn không * thực sự * cẩn thận. – jalf

3

scoped_ptr hoạt động nhanh hơn nhiều từ shared_ptr. Đúng rồi. shared_ptr luôn cấp phát bộ nhớ bằng cách sử dụng trình phân bổ hoặc trình phân bổ mặc định của bạn.

5

Mục đích dự định của chúng khác nhau, vì vậy, trong nhiều trường hợp "shared_ptr vs scoped_ptr" không phải là một câu hỏi nào cả. Chắc chắn, bạn có thể sử dụng shared_ptr khi tất cả những gì bạn cần là scoped_ptr. Nhưng vấn đề là gì? shared_ptr có khả năng là một chi phí lớn hơn một chút với tất cả các tham chiếu đếm liên quan.

15

Hiệu suất - shared_ptr có nhiều chức năng hơn, nhưng cũng yêu cầu phân bổ bổ sung (nó cũng lớn hơn, nhưng hiếm khi có vấn đề).

[sửa] Phân bổ thứ hai có thể tránh được bằng cách sử dụng make_shared, nhưng sau đó weak_ptr sẽ giữ toàn bộ phân bổ ngay cả sau khi đối tượng bị hủy, có thể là vấn đề đối với các đối tượng lớn.

Expresison of Intent sử dụng scoped_ptr bạn nêu rõ hơn bạn muốn làm gì. (Trong trường hợp bạn tự hỏi - đó là một điều tốt :)). Nếu bạn làm điều này đúng, shared_ptr cũng sẽ cho biết "đối tượng này được dự định sống ngoài phạm vi này"

+3

+1 để thể hiện ý định. Trong tĩnh mạch đó, 'scoped_ptr' rất rõ ràng là' shared_ptr'. Tương tự như vậy, việc sử dụng 'std :: auto_ptr' sẽ báo hiệu rằng bạn sẵn sàng chuyển quyền sở hữu đối tượng tại một số điểm. –

1

Scoped_ptr có ít điểm chung với shared_ptr, weak_ptr hoặc unique_ptr vì nó chỉ làm trường hợp rất đặc biệt "tính tham chiếu" . Nó không phải là một cái gì đó bạn sẽ cần rất thường xuyên trong mã được thiết kế tốt, nhưng nó là một công cụ tốt để có sẵn.

Về cơ bản, scoped_ptr không phải là điều được tính tham chiếu. Thay vào đó, nó là một đối tượng bạn tạo trên stack (trong phạm vi địa phương) để bạn có thể làm điều gì đó như thế này:

//Some enclosing scope- anything set off by "{}" or even a function: 
    { 
     scoped_ptr<MyObject> ptr = new MyObject(parameters...); 
    } // When we hit this closing brace, "ptr" will delete the "MyObject" inside. 

Bạn có xu hướng để xem mô hình này nhiều hơn với mutexes và đồng bộ hóa khác primatives- tôi có thể tuyên bố một "AutoLock" sẽ khóa mutex được truyền vào nó, sau đó mở khóa nó khi nó xóa toàn bộ phạm vi "{}" thành một phần quan trọng.

Cũng lưu ý rằng một 'scoped_ptr' chỉ bao giờ có ý nghĩa khi bạn không thể chỉ làm một phân bổ ngăn xếp đồng bằng cũ như "MyObject obj (params ..)" vì một lý do nào đó. Sau khi tất cả, những gì nó đang làm là cho phép bạn sử dụng một đối tượng phân bổ heap như thể nó là một trên stack.Điều đó có xu hướng hiếm hơn nhiều so với trường hợp sử dụng so với việc đếm tham chiếu của shared_ptr & người anh em họ của nó.

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