我的班级可以有孩子,所以我需要公开迭代器。 render类需要反向迭代它们,这就是我有反向迭代器的原因。但是有没有办法减少这些因为它似乎很多:
std::vector<AguiWidget*>::iterator getChildBeginIterator();
std::vector<AguiWidget*>::reverse_iterator getChildRBeginIterator();
std::vector<AguiWidget*>::iterator getChildEndIterator();
std::vector<AguiWidget*>::reverse_iterator getChildREndIterator();
std::vector<AguiWidget*>::const_iterator getChildBeginIterator() const;
std::vector<AguiWidget*>::const_reverse_iterator getChildRBeginIterator() const;
std::vector<AguiWidget*>::const_iterator getChildEndIterator() const;
std::vector<AguiWidget*>::const_reverse_iterator getChildREndIterator() const;
std::vector<AguiWidget*>::iterator getPrivateChildBeginIterator();
std::vector<AguiWidget*>::reverse_iterator getPrivateChildRBeginIterator();
std::vector<AguiWidget*>::iterator getPrivateChildEndIterator();
std::vector<AguiWidget*>::reverse_iterator getPrivateChildREndIterator();
std::vector<AguiWidget*>::const_iterator getPrivateChildBeginIterator() const;
std::vector<AguiWidget*>::const_reverse_iterator getPrvateChildRBeginIterator() const;
std::vector<AguiWidget*>::const_iterator getPrivateChildEndIterator() const;
std::vector<AguiWidget*>::const_reverse_iterator getPrivateChildREndIterator() const;
由于
答案 0 :(得分:13)
那些对我来说很好看。或者,如果不知道你究竟在做什么,我就无法准确评论。但有一点你可以肯定做任何事情:你为什么不使用typedef
?如果您使用typedef
,您也可以在课外使用它,意味着在客户端代码中,您将使用该类!
例如,
class sample
{
public:
//make these typedef public so you use it from outside!
typedef std::vector<AguiWidget*>::iterator iterator ;
typedef std::vector<AguiWidget*>::reverse_iterator reverse_iterator;
typedef std::vector<AguiWidget*>::const_iterator const_iterator;
typedef std::vector<AguiWidget*>::const_reverse_iterator const_reverse_iterator;
iterator child_begin();
reverse_iterator child_rbegin();
iterator child_end();
reverse_iterator child_rend();
const_iterator child_begin() const;
const_reverse_iterator child_rbegin() const;
const_iterator child_end() const;
const_reverse_iterator child_rend() const;
};
//Usage
sample s;
sample::iterator it= s.child_begin();
//see this ^^^^^^^^ how we use the typedef here!
这看起来更好!基本上typedef
封装了实现,因为它可以帮助您隐藏类的实现细节;例如,您在课堂上使用的容器std::vector
,std::list
或什么?再次查看上面的 Usage 插图;只是通过查看它你不能说容器类型,可以吗?
另请注意,我也更改了功能名称。我觉得这很好。毕竟,STL仅使用begin
和end
而不是beginIterator
和endIterator
。然而,小写是我的口味,你可能仍然更喜欢大写的一致性!
在我看来,const
函数没有多大意义,如果你想公开只读迭代器,你可能想要以下一组函数!
const_iterator readonly_child_begin();
const_reverse_iterator readonly_child_rbegin();
const_iterator readonly_child_end();
const_reverse_iterator readonly_child_rend();
//Usage
sample s;
sample::const_iterator cit= s.readonly_child_begin();
//see this ^^^^^^^^ how we use the typedef here!
答案 1 :(得分:2)
没有固定答案,但问自己以下问题:
否则,这似乎完全没问题;迭代器可能需要类中的大量代码,但使用起来很方便。 (您应该看到我的多态XQuery支持XML集合的迭代器,它包含来自第三方库的几个不同的非STL兼容迭代器......)
一些评论者提出的typedef
建议是一个好主意,因为它提供了更好的封装,即使编译器没有强制执行封装。
答案 2 :(得分:2)
将此接口切成两半的简单方法是使用范围而不是begin()/ end()对。例如,请参阅Boost的iterator_range。或者您可以返回对容器的引用,但是您可以只获取const_iterator
或者您可以让外部修改您可能不需要的容器。
请注意,矢量迭代器是双向的,因此您可以再次使用一半的方法,而不会暴露较少的功能。如果您确实需要使用++
而不是--
,则可以使用外观,例如Boost的reverse_iterator。
请注意,这些内容(范围和reverse_iterator外观)在概念上都很简单,您可以自己轻松地构建它们(尽管正确可能需要大量工作)。
无论哪种方式,4种功能而非16种声音对我来说都是非常合理的。
答案 3 :(得分:1)
您可以通过mixin界面实现此目的:
template<int Tag> class IteratorRange {
private:
std::vector<AguiWidget*>& range;
public:
IteratorRange(std::vector<AguiWidget*>& range) : range(range) {}
typedef std::vector<AguiWidget*>::iterator iterator ;
typedef std::vector<AguiWidget*>::reverse_iterator reverse_iterator;
typedef std::vector<AguiWidget*>::const_iterator const_iterator;
typedef std::vector<AguiWidget*>::const_reverse_iterator const_reverse_iterator;
iterator begin();
reverse_iterator rbegin();
iterator end();
reverse_iterator rend();
};
enum { PublicChild, PrivateChild };
class MyClass : public IteratorRange<PublicChild>, private IteratorRange<PrivateChild> {
MyClass() : IteratorRange<PublicChild>( ??? ), IteratorRange<PrivateChild>( ??? ) { }
typedef IteratorRange<PublicChild> Public; // For MyClass::Public::begin etc
};
答案 4 :(得分:0)
根据您对这些迭代器的操作,您可以公开某种访问者函数:
template<class UnaryFunction>
void visit(UnaryFunction & f) {
// apply function to each element in vector
}
您可以根据需要调整该签名,但这可能会使界面更加纤薄。
答案 5 :(得分:0)
是的,主要是。标准库容器也这样做。欢迎来到C ++!
但是,我会重新考虑“私人”的。我甚至不能说出它们应该是什么,但它不可能是好的。
我还会添加一些带有typedef
关键字的成员类型别名,以使返回类型更加封装。
答案 6 :(得分:-1)
您已经公开了std :: vector :: iterator,这意味着您已经公开了许多实现细节。
返回const std :: vector&amp;,const引用可以减少大部分接口并提供更多功能。否则,将来你可能需要添加类似getChildSize(),getXXXSize()等的东西。