2014-05-06 35 views
18

Tôi có vấn đề như: Tôi có lớp Foo, và nếu có một số đối tượng của lớp này, std :: vector tài liệu tham khảo

Foo a(); 

tôi cần phải đưa đối tượng này đến 2 vectơ khác nhau:

std::vector<Foo> vA, vB; 

và nếu a thay đổi trong vA nó nên được thay đổi trong vB, vector vAvB có thể khác nhau, nhưng họ có thể h ave cùng một đối tượng. Tôi biết rằng nó có thể làm với Boost, nhưng tôi không thể sử dụng Boost.

+3

Ý của bạn là sử dụng [ 'std :: vector >'] (http://en.cppreference.com/w/cpp/memory/shared_ptr)? –

+4

Lưu ý rằng một tuyên bố như 'Foo a(); 'không làm những gì bạn nghĩ. Nó thực sự là một khai báo của một hàm 'a' không có đối số và trả về một đối tượng' Foo'. –

+3

Không chắc chắn nếu những gì 'Foo a()' là * nghĩa là * có nghĩa là, nhưng nó tuyên bố một hàm gọi là 'a' trả về một' Foo'. –

Trả lời

39

Có một số khả năng:

  1. cửa hàng một vector của các con trỏ (sử dụng nếu vectơ của bạn sở hữu cổ phần của con trỏ):

    std::vector<std::shared_ptr<Foo>> vA, vB; 
    
  2. cửa hàng một vector của các tài liệu tham khảo gói (sử dụng nếu các vectơ không chia sẻ quyền sở hữu của con trỏ, và bạn biết đối tượng tham chiếu hợp lệ quá khứ đời của các vectơ):

    std::vector<std::reference_wrapper<Foo>> vA, vB; 
    
  3. lưu trữ một vector của con trỏ thô (sử dụng nếu vectơ của bạn không chia sẻ quyền sở hữu của các con trỏ, và/hoặc các con trỏ lưu trữ có thể thay đổi tùy thuộc vào các yếu tố khác):

    std::vector<Foo*> vA, vB; 
    

    Điều này là phổ biến cho quan sát, theo dõi phân bổ, vv Các thông báo trước cho con trỏ thô áp dụng: Không sử dụng các con trỏ để truy cập các đối tượng sau khi kết thúc thời gian cuộc sống của họ.

  4. cửa hàng một vector của std::unique_ptr rằng quấn đối tượng (sử dụng nếu vectơ bạn muốn bàn giao quyền sở hữu của các con trỏ trong trường hợp đó tuổi thọ của các đối tượng tham chiếu được điều chỉnh bởi các quy tắc của std::unique_ptr lớp):

    std::vector<std::unique_ptr<Foo>> vA, vB; 
    
+1

Nhận xét về việc không sử dụng 'shared_ptr' trừ khi trong điều kiện khắc nghiệt chỉ là sai. Nếu con trỏ là để điều hướng (trường hợp thường xuyên nhất), bạn nên _not_ sử dụng 'shared_ptr'. –

+0

Trong ví dụ của OP, anh ta dường như có ý định rằng các đối tượng của anh ta được phân bổ trên stack, vì vậy tôi đồng ý với @JamesKanze trong đó đề xuất con trỏ thông minh mạnh mẽ của bạn là không phù hợp và có khả năng gây hiểu nhầm. – JBentley

+0

@JamesKanze, cảm ơn - Tôi đã cập nhật bài đăng của mình. – utnapistim

2

Thay vì giữ Foo làm đối tượng giữ làm con trỏ để phản đối Foo, ví dụ:

std::vector<Foo *> vA, vB; 

và quản lý phân bổ và deallocations cẩn thận để tránh rò rỉ bộ nhớ (Phân bổ nhưng không deallocating khi thực hiện). Nếu bạn phân bổ một đối tượng Foo và giữ con trỏ trong cả vA và vB, thì bạn đang giữ đối tượng cơ bản giống nhau trong cả hai thông qua con trỏ. Nếu không, bạn có thể sử dụng con trỏ thông minh (tốt hơn) tham khảo:

What is a smart pointer and when should I use one?

+0

Tôi đoán mọi người đang downvoting vì có các tùy chọn không yêu cầu (mis-) quản lý thủ công các con trỏ đó (các con trỏ thông minh như 'shared_prt') sẽ thích hợp hơn. – Mat

+0

@Mat: Đặc biệt là từ * cẩn thận * biết rằng tất cả chúng ta đều có một hoặc hai ngày xấu. –

+0

bạn là đúng, có hai lựa chọn, sử dụng một con trỏ được quản lý hoặc quản lý con trỏ của riêng bạn tùy thuộc vào chuyên môn. –

7

Bạn cần một vé tham chiếu. Và kể từ khi bạn chỉ định rằng bạn cần phải sử dụng std :: vector, sau đó điều chính xác để làm là bọc các đối tượng của bạn trong std::reference_wrapper.This page from C++ reference nên giải thích nó độc đáo:

vector<reference_wrapper<Foo>> vA, vB; 
vA.push_back(a); 
vB.push_back(a); // puts 'a' into both vectors 

// make changes to 'a' 
// use .get() to get the referenced object in the elements of your vector 
// vA[0].get() == vB[0].get() 
+0

Điều này làm cho nó không thể (tôi nghĩ) để thay đổi bất kỳ con trỏ (đó là một tính năng hoặc một khiếm khuyết, tùy thuộc vào những gì bạn đang làm với 'vector'). –

+0

Yêu cầu duy nhất từ ​​OP là lưu trữ các tham chiếu đến đối tượng Foo, vì vậy không có con trỏ nào ở đây để có thể thay đổi. Lập trình viên tự do thay đổi nội dung của một trong hai vectơ và bất kỳ thuộc tính nào của biến 'a' bất kỳ lúc nào. Bản thân tham chiếu là, theo định nghĩa, không thay đổi. – alpartis

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