2011-11-20 46 views
12

Có hợp pháp để có một vectơ tham chiếu đến các đối tượng, như sau không?Vectơ tham chiếu đến các đối tượng

vector<Agent&> seenAgents; 

Ví dụ nào sẽ được điền bởi một số, nhưng không phải tất cả các đối tượng trong hiện trường?

Tôi có vectơ đối tượng đại lý, nhưng vectơ được phác thảo ở trên sẽ chỉ chứa tham chiếu đến các đối tượng mà mỗi tác nhân hiện có thể thấy - nghĩa là các tham chiếu sẽ được thêm và xóa mọi lúc.

Đây có phải là ngôn ngữ sẽ cho phép không? Và ngoài ra, có bất cứ điều gì khác tôi cần phải nhận thức được? Nếu tôi loại bỏ một tham chiếu từ vectơ thì nó có tồn tại ở đâu không? Nó có bị rò rỉ bộ nhớ không?

tôi dường như nhận được lỗi này trên dòng tuyên bố vector:

error C2528: 'pointer' : pointer to reference is illegal 

là một cái gì đó này trực tiếp để làm với dòng hoặc là nó rất có thể xảy ra ở một nơi khác? Nó đang được khởi tạo trong các nhà thầu initialiser danh sách như thế này:

seenAgents(vector<Agents&>()) 
+0

Bản sao của http://stackoverflow.com/questions/922360/why-cant-i-make-a-vector-of-references –

Trả lời

19

Bạn không thể có vector tài liệu tham khảo, như một tài liệu tham khảo là không copyable chuyển nhượng và tất cả STL container có nghĩa vụ phải lưu trữ copyable chuyển nhượng mặt hàng.

Nhưng bạn có thể làm cho vùng chứa giữ con trỏ. Như thế này:

vector< Agents* > seenAgents; 

Đây là một chút nguy hiểm. Bạn cần đảm bảo rằng các con trỏ này sẽ vẫn hợp lệ. Ý tôi là - nếu ai đó xóa một đối tượng, được trỏ bởi một con trỏ trong vùng chứa này, con trỏ sẽ trở thành không hợp lệ. Bạn cần phải chắc chắn rằng điều này sẽ không xảy ra, bởi vì bạn không thể kiểm tra nó (bạn không thể kiểm tra NULL, bởi vì một con trỏ sẽ không trở thành NULL, nếu ai đó xóa đối tượng nhọn).

Giải pháp tốt nhất ở đây (được cung cấp bởi vùng chứa con trỏ) sẽ là sử dụng một số con trỏ thông minh - một số có số tham chiếu, ví dụ; họ sẽ đảm bảo với bạn rằng đối tượng sẽ tồn tại và con trỏ đó là hợp lệ. Và trong trường hợp đối tượng, được trỏ bởi con trỏ thông minh, bị phá hủy, bạn có thể kiểm tra nó cho NULL.

+2

Bạn có chắc chắn không thể sao chép các tham chiếu không? Tôi đã nghĩ rằng họ không thể chuyển nhượng được. – UncleBens

+0

Phải, cảm ơn. Nhưng bạn vẫn không thể "sao chép" một tham chiếu, vì nó không phải là một loại thực, nó không thực sự tồn tại, ý tôi là - không có phân bổ cho nó (trong hầu hết các trình biên dịch, chắc chắn - tất cả chúng). Nhưng vẫn - yep, 'assignable' có vẻ đúng hơn và ít gây nhầm lẫn hơn. Đã chỉnh sửa :) –

+0

Bạn không thể mặc định xây dựng chúng. –

8

Bạn không thể làm điều đó. Sử dụng con trỏ.

Thư viện Boost cung cấp PTR_VECTOR mà là một giải pháp tốt hơn:

vector<T*> foo; 
+2

Tại sao 'ptr_vector' tốt hơn thì' vector '. Khi bạn nói điều gì đó tốt hơn thì một cái gì đó khác mô tả số liệu của bạn. – tomas789

+1

Có nhiều lý do tại sao 'ptr_vector's là tốt hơn, bạn có thể [đọc về nó ở đây] (http://www.boost.org/doc/libs/1_55_0/libs/ptr_container/doc/examples.html). Nhưng, tóm lại, chúng hoạt động giống như một véc tơ của các tài liệu tham khảo và do đó, thường an toàn hơn để sử dụng. Ví dụ, bạn không dereference con trỏ mình và bạn không thể lưu trữ một con trỏ 'NULL' trong vector. – edam

+1

Rất tiếc, tôi muốn nói "bạn không thể lưu trữ con trỏ' NULL' trong vectơ "* theo mặc định *! – edam

2

tôi muốn chức năng tương tự. Cuối cùng, đây là những gì tôi đã làm:

template <class T> class VectorOfRefs : public std::vector<T *> { 
public: 
    inline T & at(const uint64_t i) { 
     T * x = std::vector<T *>::at(i); 
     return *x; 
    } 
}; 

VectorOfRefs <MyType> myVector; 
myVector.push_back(&myInstance0); 
myVector.push_back(&myInstance1); 

// later in the code: 
myVector.at(i).myMethod(); 

Rõ ràng đây là vectơ của con trỏ bên dưới bìa.

Thông thường tôi sẽ sử dụng STL và giải quyết cho myVector.at(i)->myMethod(), nhưng tôi muốn sử dụng toán tử ++, vì vậy tôi có hai tùy chọn sau:

// using STL: 
(*myVector.at(i))++; 

// or, using my wrapper: 
myVector.at(i)++; 

tôi thấy các ký hiệu với wrapper xa thích hợp hơn trong điều kiện của khả năng đọc mã. Tôi không thích các wrapper, mỗi se, nhưng nó trả cổ tức sau đó.

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