Представление станд.:: перечислите как только для чтения

У меня есть класс, который содержит, среди прочего, станд.:: список. Я хочу выставить этот список, но только таким способом, которым структурой и данными он содержит, только для чтения, но все еще может использоваться с итераторами.

Путем у меня есть он, 'рабочий' банкомат должен возвратить копию списка. Этот отпуск мой класс 'безопасный', но конечно не делает ничего, чтобы мешать вызывающей стороне изменить их копию списка и не получить правильные данные.

Существует ли лучший путь?

8
задан Tim Jones 4 June 2010 в 07:16
поделиться

5 ответов

Почему бы не вернуть const std :: list & вместо этого?

16
ответ дан 3 November 2019 в 12:49
поделиться

Вместо того, чтобы открывать сам список (вообще), просто выставьте const_iterator до его начала и конца. См. cbegin () и cend () для помощи в этом ...

9
ответ дан 3 November 2019 в 12:49
поделиться

Верните константную ссылку:

const std::list<T>& getList() const;

или просто верните константные итераторы:

std::list<T>::const_iterator getListBegin() const;
std::list<T>::const_iterator getListEnd() const;
4
ответ дан 3 November 2019 в 12:49
поделиться

Существует проблема зависимости в предоставлении доступа к члену данных внешнему миру.

Если вы решите изменить свой атрибут на что-то лучшее (потому что list - последний контейнер), или потому что у вас есть новые требования, то это повлияет на всех ваших клиентов, и это плохо.

Одна простая альтернатива - предложить typedef :

typedef std::list<Foo>::const_iterator const_iterator;

ЕСЛИ ваши клиенты используют ваш псевдоним, то это простой вопрос перекомпиляции кода.

Другой альтернативой является создание собственного класса итератора (не так уж сложно), в который будет встроен сам итератор.

class const_iterator
{
public:

private:
  typedef std::list<Foo>::const_iterator base_type;
  base_type mBase;
};

Вы просто перенаправляете все операции фактическому итератору, и ваши клиенты (хотя им придется перекомпилировать, если вы меняете контейнер) не могут случайно использовать неализованный тип.

Затем третье решение похоже на первое, за исключением того, что вы абстрагируете тип ... хотя оно довольно неэффективно (для списка), поэтому я бы не советовал его: предполагается, что итераторы дешево копировать, вы не хотите ничего нового .

4
ответ дан 3 November 2019 в 12:49
поделиться
class foo {
  private:
     typedef std::list<bar> bar_cont_t;

  public:
     typedef bar_const_t::const_iterator bar_const_iterator;

     bar_const_iterator bar_begin() const {return bar_data_.begin();}
     bar_const_iterator bar_end  () const {return bar_data_.end  ();}

     // whatever else

  private:
     bar_cont_t bar_data_;
};
3
ответ дан 3 November 2019 в 12:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: