В этой ситуации я хотел бы забыть о возвращении vector
(или ссылки на него). Вызывающий не может вносить какие-либо изменения, поэтому ему не нужно видеть какой-либо конкретный контейнер. Другие ответы объясняют, почему вы не можете ссылаться на свой вектор, как если бы он был вектором const someObj*
. В этом отношении, если в будущем вы измените свой класс на deque
вместо vector
, вы не сможете вернуть ссылку на него, как если бы это был вектор. Поскольку вызывающим просто необходим доступ к элементам, давайте дадим им следующее:
const someObj *getInfoAt(size_t n) const {
return _myVector.at(n);
}
const_info_iterator getInfoBegin() const {
return _myVector.begin();
}
const_info_iterator getInfoEnd() const {
return _myVector.end();
}
size_t getInfoSize() const {
return _myVector.size();
}
// plus anything else they need.
const_info_iterator
- это typedef для класса, который немного раздражает при написании. Он должен обернуть std::vector<someObj *>::const_iterator
и соответствовать типу operator*
. boost::transform_iterator
может быть полезно, или это не так уж плохо писать с нуля. Однако двунаправленные итераторы требуют большинства перегрузок операторов.
Теперь, если вызывающий действительно хочет вектор const someObj*
, то с помощью моего интерфейса они могут легко получить снимок в любой конкретный момент:
std::vector<const someObj*> mycopy(myinfo.getInfoBegin(), myinfo.getInfoEnd());
Чего они не могут иметь, так это vector
, который постоянно отражает изменения, сделанные в каком-то другом vector
другого типа где-то еще - std::vector
просто не делает этого.