Векторы ссылок на объекты
Является ли законным иметь вектор ссылок на объекты, например:
vector<Agent&> seenAgents;
Что, например, будет заполнено некоторыми, но не всеми объектами сцены?
У меня есть вектор объектов агента, но вектор, описанный выше, должен содержать ссылки только на те, которые может видеть каждый агент, что означает, что ссылки будут добавляться и удаляться все время.
Это что-то, что позволит язык? И кроме того, есть ли что-то еще, о чем я должен знать? Если я удалю ссылку из вектора, она будет сохраняться где угодно? Это утечка памяти?
Кажется, я получаю эту ошибку в строке, объявляющей вектор:
error C2528: 'pointer' : pointer to reference is illegal
Это что-то прямое с линией, или это, скорее всего, происходит где-то в другом месте? Он инициализируется в списке инициализаторов конструкторов следующим образом:
seenAgents(vector<Agents&>())
Ответы
Ответ 1
У вас не может быть vector
ссылок, поскольку ссылка не присваивается copyable и все контейнеры STL должны хранить скопировать назначаемые элементы.
Но вы можете сделать контейнер для хранения указателей. Вот так:
vector< Agents* > seenAgents;
Это немного опасно. Вы должны быть уверены, что эти указатели останутся действительными. Я имею в виду - если кто-то удаляет объект, указанный указателем в этом контейнере, указатель становится недействительным. Вы должны быть уверены, что этого не произойдет, потому что вы не можете проверить его (вы не можете проверить NULL
, потому что указатель не станет NULL
, если кто-то удалит указанный объект).
Лучшим решением здесь (предоставляемым контейнером с указателями) было бы использование некоторых интеллектуальных указателей - например, с подсчетом ссылок; они гарантируют вам, что объект будет существовать и что указатель действителен. И в случае уничтожения объекта, отмеченного умным указателем, вы можете проверить его на NULL
.
Ответ 2
Вы не можете этого сделать. Используйте указатели.
Библиотека Boost предоставляет PTR_VECTOR, что является лучшим решением, чем:
vector<T*> foo;
Ответ 3
Мне нужна была аналогичная функциональность. В конце концов, вот что я сделал:
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();
Очевидно, что это вектор указателей под обложками.
Обычно я использовал STL и соглашался на myVector.at( i )->myMethod()
, но я хотел использовать оператор ++, поэтому у меня были следующие два варианта:
// using STL:
(*myVector.at(i))++;
// or, using my wrapper:
myVector.at( i )++;
Я считаю, что обозначение с оберткой намного предпочтительнее с точки зрения удобочитаемости кода. Мне не нравится оболочка, по сути, но она выплачивает дивиденды позже.