如何隐藏我的内部集合但允许用户迭代他?

时间:2014-05-22 08:07:28

标签: c++ stl

我有很多类在list<cats>内,我希望允许使用我的类的用户迭代我拥有的猫,所以我通过编写以下函数让他们访问const迭代器: / p>

list<cats>::const_iterator GetIterator()
{
    //return the iterator
}

现在我想改变我的类的实现并使用vector而不是list,所以我需要返回vector的const迭代器。

问题是,现在每个使用我的班级的人都需要将他们的代码从list<cats>::const_iterator更改为vector<cat>::const_iterator

如果所有迭代器都继承自&#34;转发迭代器&#34;这将非常有用。

我的主要问题是我如何解决这个问题,我不想从一个集合中继承。

另一个非常相关的问题是为什么STL的设计者选择不继承迭代器? (例如,随机访问迭代器可以从前向迭代器继承,他具有所有它的功能)

在我提出问题之前,我做了相当广泛的搜索,但无法找到解决方案。 我发现问题的最接近的是这个,但这不是我的问题。 Give access to encapsulated container

3 个答案:

答案 0 :(得分:2)

从您的类中公开迭代器类型,例如:

class a
{
  vector<int> g;
public:
  typdef vector<int>::const_iterator const_iterator;

  const_iterator begin() const
  { return g.begin(); }

  : // etc

};

答案 1 :(得分:0)

如果用户可以重新编译代码,您可以使用

typedef list<cats> CatList;
在您的包含文件中

。然后,如果要更改容器,请将其更改为

typedef vector<cats> CatList;

并且用户将使用例如。

CatList::iterator it;

然而,这不是一个好习惯;不同容器的迭代器可能看起来相同但行为不同,例如从向量中删除项目会使所有迭代器无效,但在列表上执行相同操作只会影响已删除项目的迭代器。如果有一天你想使用std::map<some_key,cats>,那么就不提这个案例了。

答案 2 :(得分:0)

我同意Nim的回答,并希望提供我所遵循的风格,我认为这样可以使维护变得更容易,因为现在更改基础容器类型对于您的班级用户来说根本不需要任何工作,而且当您的工作很少时保持你的班级。

class A
{
  // change only this to change the underlying container:
  // Don't Repeat Yourself!

  using container_t = std::vector<int>;               




public:

  // constructor from a copy of a container
  A(container_t source) 
  : _myContainer { std::move(source) } 
  {}

  // this derived type is part of the public interface
  using const_iterator_t = container_t::const_iterator; 

  // following your function naming style...
  const_iterator_t GetIterator() const { return /* some iterator of _myContainer */; }
  const_iterator_t GetEnd() const { return std::end(_myContainer); }


private:
  container_t _myContainer;
};