Часто возникает ситуация, когда имеем некий класс, который держит список (вектор/очередь и т.д.) некий объектов которыми он как-то манипулирует.
class Manipulator
{
public:
void Add(const Entity& element);
void DoSmth();
private:
std::list<Entity> mEntityList;
};
Кроме всего прочего, этот класс должен предоставлять некий доступ к элементам этого списка внешним пользователям (обычно это не изменяющие список и его элементы действия -- найти кого-то, что-то посмотреть, узнать сколько их там вообще и т.д. и т.п.).
Вопрос -- как это грамотней сделать?
Продублировать функции доступа (кроме Add добавить Get, ElementsCount, GetById (?), GetNext and so on)?
Наваять собственный самодельный итератор и возвращать его? (+ функции возвращающие итераторы эти на начало и конец).
Опубликовать константную ссылку на этот список?
Написать функцию для получения оной константной ссылки?
Написать оператор приведения нашего Манипулятора к стандартному контейнеру (в данном случае списку)?
У кого какие ещё идеи?
Пардон за опечатку в заголовке темы. Конечно же доступа.
А>Часто возникает ситуация, когда имеем некий класс, который держит список (вектор/очередь и т.д.) некий объектов которыми он как-то манипулирует.
А>А>class Manipulator
А>{
А>public:
А> void Add(const Entity& element);
А> void DoSmth();
А>private:
А> std::list<Entity> mEntityList;
А>};
А>
А>Кроме всего прочего, этот класс должен предоставлять некий доступ к элементам этого списка внешним пользователям (обычно это не изменяющие список и его элементы действия -- найти кого-то, что-то посмотреть, узнать сколько их там вообще и т.д. и т.п.).
А>Вопрос -- как это грамотней сделать?
Задача класса — выполнять свои обязанности. Нужно ему при этом хранить список/вектор/etc. или нет — дело второстепенное. В первоначальной постановке наоборот — вот есть спрятанный контейнер и неизвестно какой интерфейс к нему необходим. Поэтому возникает вопрос — зачем вообще нужен этот класс ? Из ответов уже можно собирать требования к интерфейсу.
Почему, например не так:
void DoSmthA(std::list<Entity>&);
void DoSmthB(std::list<Entity>&);
?
А>Продублировать функции доступа (кроме Add добавить Get, ElementsCount, GetById (?), GetNext and so on)?
Опять же, в чем тогда принципиальное отличие класса Manipulator
от простого контейнера?
А>Наваять собственный самодельный итератор и возвращать его? (+ функции возвращающие итераторы эти на начало и конец).
А>Опубликовать константную ссылку на этот список?
А>Написать функцию для получения оной константной ссылки?
А>Написать оператор приведения нашего Манипулятора к стандартному контейнеру (в данном случае списку)?
Зависит от задачи, но потенциально хуже, т.к. эти способы легко могут нарушать инварианты, и они завязаны на реализацию.