Подтвердить что ты не робот

Векторы ссылок на объекты

Является ли законным иметь вектор ссылок на объекты, например:

vector<Agent&> seenAgents;

Что, например, будет заполнено некоторыми, но не всеми объектами сцены?

У меня есть вектор объектов агента, но вектор, описанный выше, должен содержать ссылки только на те, которые может видеть каждый агент, что означает, что ссылки будут добавляться и удаляться все время.

Это что-то, что позволит язык? И кроме того, есть ли что-то еще, о чем я должен знать? Если я удалю ссылку из вектора, она будет сохраняться где угодно? Это утечка памяти?

Кажется, я получаю эту ошибку в строке, объявляющей вектор:

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

Это что-то прямое с линией, или это, скорее всего, происходит где-то в другом месте? Он инициализируется в списке инициализаторов конструкторов следующим образом:

seenAgents(vector<Agents&>())
4b9b3361

Ответ 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 )++;

Я считаю, что обозначение с оберткой намного предпочтительнее с точки зрения удобочитаемости кода. Мне не нравится оболочка, по сути, но она выплачивает дивиденды позже.