实际上,我在这里有一个设计问题。它非常简单但重点是:
我有一个C ++类,它有一个STL向量,声明为私有成员。但是该类的客户端需要遍历此向量。
在C#中,我们有一个非常方便的语句,Yield,在这种情况下,你编写一个函数返回一个IEnumerable,它“产生”你一个很好的方法来迭代该类中的私有容器。
我只是想为C ++找到一个优雅的解决方案,而不是使用像GetValue(int idx)这样的方法。
有什么建议吗?
示例:
class Fat
{
public:
Fat();
// some code here ...
private:
void LoadSectors(SECT startPoint);
std::vector<SECT>sectors;
};
class Storage
{
public:
Storage(string CompoundFile);
//For example, this method will receive a ref to my fat system and iterate over
//the fat array in order to read every sector.
LoadStrem(Fat& fat);
};
这是一个非常简单的例子。
答案 0 :(得分:6)
C ++中没有类似于yield
的C ++中的语法糖。如果你想创建一个类,其实例应该以与库存STL集合相同的方式迭代,那么你必须为你的类实现一个迭代器,在你的类型上将其公开为::iterator
,然后提供{{ 1}}和begin()
成员函数。
答案 1 :(得分:4)
您可以创建一个访问器函数,它向向量返回一个引用(或最好是const引用),或者您可以创建返回适当向量迭代器的begin()
和end()
访问器函数。
答案 2 :(得分:2)
当您需要发布班级内部时,它总是很痛苦......
你可以通过像stl那样提供算法来解决它:在对象的接口上提供foreach
函数。
class S {
std::vector<int> v;
public:
//... and some methods to populate the vector
template< typename F > F& foreach( F& f ) {
return std::for_each( v.begin(), v.end(), f );
}
};
这样,课程仍然“关闭”,但您可以获得所需的灵活性。您还可以添加copy
函数,也可以添加transform
;这些是我最常需要的。
答案 3 :(得分:1)
让你的类暴露迭代器。
class Fat
{
public:
typedef std::vector<SECT>::iterator iterator;
iterator begin() { return sectors.begin(); }
iterator end() { return sectors.end(); }
Fat();
// some code here ...
private:
void LoadSectors(SECT startPoint);
std::vector<SECT>sectors;
然后周围的代码可以通过一对迭代器自由遍历向量的元素。