2010-09-29 8 views
16

Tôi cần một hộp chứa con trỏ. Bạn có đề xuất boost::ptr_vector<T> hoặc std::vector<boost::shared_ptr<T> > không? (Hoặc cái gì khác?)Tôi có nên sử dụng boost :: ptr_vector <T> hoặc vector <boost :: shared_ptr <T>>?

Nếu điều đó quan tâm, cấu trúc dữ liệu thực tế của tôi tương đối phức tạp (xem here) và hiện đang lưu trữ các đối tượng, chứ không phải con trỏ, nhưng tôi muốn thay đổi (sử dụng các vùng chứa con trỏ), theo thứ tự để loại bỏ việc sao chép không cần thiết:

typedef std::multimap<Foo0, std::map<int, double> > VecElem; 
std::vector<VecElem> vec; 
+0

nơi sao chép không cần thiết này xảy ra? –

+0

@Idan: Bất cứ lúc nào bạn chèn thứ gì đó vào vectơ hoặc multimap từ trên cao. – Frank

+3

@Idan: Khi bạn có một thùng chứa lưu trữ con trỏ, chỉ con trỏ sẽ được sao chép khi thêm dữ liệu, khi bạn lưu trữ các đối tượng, các đối tượng thực tế sẽ được sao chép. Đây là một vấn đề khi bạn đang đối phó với các đối tượng đắt tiền để sao chép. – sbi

Trả lời

30

Ai sở hữu đối tượng? Nếu vật chứa chứa vật thể (nghĩa là vật thể không được lâu hơn thùng chứa), hãy sử dụng ptr_vector. Nếu không, hãy sử dụng vectơ của shared_ptr s. Thùng chứa thư viện chuẩn (chẳng hạn như std::vector hoặc std::list) sở hữu các đối tượng mà chúng chứa, vì vậy ngữ nghĩa của một số ptr_vector gần hơn.

+0

Câu hỏi Add'l: là 'vectơ' của' unique_ptr' giống với 'ptr_vector'? –

+0

@Didier: Tôi không biết đủ về 'unique_ptr' để trả lời câu hỏi đó. Tuy nhiên, 'ptr_vector' sẽ có ít chi phí hơn (như @sbi chỉ ra câu trả lời của anh ta). –

+8

@Didier: không, 'ptr_vector' cho phép sao chép' vector', bản sao sâu nội dung (sử dụng chức năng miễn phí 'new_clone') và do đó cho phép các thùng chứa đa hình. Nó cũng có giao diện đẹp hơn (dereferencing các iterator mang lại một tham chiếu đến đối tượng, không phải là một tham chiếu đến con trỏ đến đối tượng) và các tính năng khác. –

13

shared_ptr<> không có ngữ nghĩa chủ sở hữu được chia sẻ, được thực hiện thông qua tăng và giảm số lượng tham chiếu. Điều đó đi kèm với một số chi phí, đặc biệt là khi đa luồng được kích hoạt (bởi vì các quầy sau đó phải được khóa).

Nếu đối tượng của bạn được chia sẻ, hãy sử dụng shared_ptr<>.
Nhưng nếu chúng được sở hữu một cách hiệu quả bởi container, và phải chết với container, và tham chiếu (con trỏ) đưa ra có thể chết cũng khi container chết, sau đó sử dụng container con trỏ, bởi vì chúng có ít chi phí.
Nếu bạn không chắc chắn, hãy sử dụng shared_ptr để an toàn. Nếu hóa ra bạn có vấn đề về hiệu suất, bạn luôn có thể tối ưu hóa sau này. (Việc tối ưu hóa hệ thống làm việc dễ dàng hơn để có được một hệ thống được tối ưu hóa sớm.)

+6

+1 cho 'Sẽ dễ dàng hơn để tối ưu hóa hệ thống làm việc sau đó để có được hệ thống tối ưu hóa hoạt động sớm.' – balki

+0

+1 cho _" nên chết với vùng chứa "_. – mskfisher