我应该为只是向量包装的类编写迭代器吗?
我的班级中唯一一个名为Record的私有成员是一个向量。
我希望能够做到这一点:
for (auto& elem : record) {
// do something with elem
}
其中record是Record类型。为此,我需要实现迭代器 对于Record类。但是,我也可以这样做:
for (auto& elem : record.elems) {
// do something with elem
}
其中record.elems是我提到的向量。但是这样 我需要将其公之于众。
另一种方法是:
for (auto& elem : record.getElems()) {
// do something with elem
}
这样我得到迭代,成员保持私密。 可能这是最好的方式。
我的主要问题是,为什么我要为Record类实现迭代器 什么时候它只是一个向量的包装?我的同事坚持要实现迭代器, 他甚至不能解释我为什么,这只是愚蠢的。
答案 0 :(得分:9)
实现迭代器将有助于封装您的类。如果在任何时间点,您决定用其他数据类型替换支持向量,则可能会破坏依赖关系。
实际上,您不需要实现迭代器。您可以typedef
将迭代器作为向量迭代器,并创建内联begin()
和end()
方法来返回向量的迭代器。
编辑:根据要求提供一个简单示例:
template <class T>
class vectorWrapper
{
typedef typename std::vector<T> backingType;
backingType v;
public:
typedef typename backingType::iterator iterator;
typedef typename backingType::const_iterator const_iterator;
iterator begin() { return v.begin(); }
const_iterator begin() const { return v.begin(); }
const_iterator cbegin() const { return v.cbegin(); } // C++11
iterator end() { return v.end(); }
const_iterator end() const { return v.end(); }
const_iterator cend() const { return v.cend(); } // C++11
};
如果需要(或想要)reverse_iterator
可以以相同的方式添加。由于这些方法很可能由编译器内联,因此使用它几乎没有开销。
答案 1 :(得分:2)
如果您的班级应该看范围,那么最好通过begin()
和end()
成员提供对迭代器的访问权限。关键的优点是类的对象可以与其他范围一致使用:对于类的使用方式并且努力程度很小也没有太大的疑问:除非你不希望你的类被使用,否则你应该使它使用起来容易和明显。当然,如果你不期望你的课程被使用,为什么还要先写它?
这些是否需要与向量的类型不同取决于您是否需要施加任何约束。如果类没有对元素或它们的顺序施加约束,那么传递迭代器就足够了。否则,可能需要创建自定义迭代器。