2012-04-23 42 views
5

Khi khởi tạo một biến thành viên shared_ptr:Khởi tạo biến thành viên shared_ptr, mới so với make_shared?

// .h 
class Customer 
{ 
public: 
    Customer(); 

private: 
    std::shared_ptr<OtherClass> something_; 
} 

// .cpp 
Customer(): 
    something_(new OtherClass()) 
{ 
} 

vs

Customer(): 
    something_(std::make_shared<OtherClass>()) 
{ 
} 

Sản phẩm phiên bản make_shared phép? Tôi luôn luôn có vẻ để xem phiên bản đầu tiên, được ưa thích?

+4

Herb Sutter vừa viết GOTW về điều này. Xem [this] (http://herbsutter.com/gotw/_103/) và cũng xem [one issue] (http://lanzkron.wordpress.com/2012/04/22/make_shared-almost-a-silver -bullet /) mà Herb không nói rõ. –

+0

@RSamuelKlatchko - Một liên kết cập nhật cho liên kết đầu tiên bạn cung cấp trong sử dụng ansewer của bạn https://herbsutter.com/2013/05/29/gotw-89-solution-smart-pointers/ –

Trả lời

11

duy nhất lúc make_sharedkhông phép là:

  1. Nếu bạn nhận được một con trỏ thường được phân bổ bởi người khác và lưu trữ nó trong shared_ptr. Đây thường là trường hợp khi giao tiếp với các API C.
  2. Nếu người xây dựng bạn muốn gọi không công khai (make_shared chỉ có thể gọi cho nhà thầu công khai). Điều này có thể xảy ra với các chức năng của nhà máy, nơi bạn muốn buộc người dùng tạo đối tượng từ nhà máy.

    Tuy nhiên, có nhiều cách để giải quyết vấn đề này. Thay vì có một hàm tạo riêng, có một hàm tạo công khai. Nhưng làm cho hàm tạo có kiểu chỉ có thể được xây dựng bởi những người có quyền truy cập riêng vào lớp đó. Bằng cách đó, những người duy nhất có thể gọi make_shared với loại đối tượng đó là những người có quyền truy cập riêng tư vào lớp học.

Vì vậy, bạn có thể thực hiện việc này.

+0

Về vấn đề tình bạn, có bất kỳ đề cập đến trong tiêu chuẩn của các chức năng cụ thể để sử dụng như bạn bè? Tôi cũng có thể hình dung một số thực hiện ủy nhiệm công việc này cho các chức năng trợ giúp ... –

+0

@MatthieuM: Tôi đã tự hỏi điều tương tự, đó là lý do tại sao tôi nói "có thể". Tôi đã hỏi tại comp.std.C++; chúng ta sẽ thấy những gì họ phải nói về nó. Nếu không, tôi nghĩ rằng nó có thể làm cho một báo cáo khiếm khuyết khá. –

3

Trong trường hợp này, việc sử dụng make_shared không chỉ được phép, nhưng tốt hơn nên sử dụng nó. Nếu bạn sử dụng mới, nó sẽ cấp phát bộ nhớ cho Khách hàng của bạn ở đâu đó và sau đó là bộ nhớ cho shared_ptr của bạn ở một nơi khác, lưu trữ cả tham chiếu mạnh và yếu (đối với con trỏ yếu và con trỏ được chia sẻ). Nếu bạn sử dụng make_shared, bạn sẽ chỉ có một nơi trong bộ nhớ với mọi thứ và do đó chỉ có một điểm mới.

Tôi không chắc chắn rằng tôi đã thực sự rõ ràng, đây là mục đích của GotW #103, đọc nó, nó cũng được giải thích ở đó.

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