我想将一些对象公开为具有stl样式操作可能性的抽象容器(for_each循环,迭代器)并隐藏容器实现细节。
性能问题无关紧要(复制“通用”迭代器时虚拟调用甚至内存分配都可以接受)。
我将编写一个带有纯虚函数的抽象容器接口(+容器上的“通用”迭代器)和一个用于stl顺序容器的实现适配器。
但也许有用于此目的的有用现有库?
或者这完全是一个坏主意?
答案 0 :(得分:2)
答案 1 :(得分:1)
如果您的“对象”不是STL对象而是自定义对象,我认为这是个好主意。
正如您在http://www.sgi.com/tech/stl/Vector.html上看到的那样,vector“是”RandomAccessContainer的模型“。大多数Boost包使用类似的概念(术语realy是“概念”)
在C ++中,你有两种可能性:
使用模板,您可以执行以下操作:
doSomething < AnythingThatIsIterable >(AnythingThatIsIterable i){
for (AnythingThatIsIterable::itertaor it = i.begin(); it != i.end(); ++i){
it->foo()
}
}
答案 2 :(得分:1)
Here is我的Java样式的前向迭代器包装器实现了一个。它很丑。提升部分是可选的,可能会被重构。
答案 3 :(得分:0)
对于“暴露C ++类以使类的用户不必在我的类实现更改时重新编译程序”的问题的最通用解决方案是pImpl模式。有关详细信息:http://en.wikipedia.org/wiki/Opaque_pointer
答案 4 :(得分:0)
我完全理解用户的问题。他/她想要一个自定义容器类,向用户公开类似STL的接口。标准STL容器在某种程度上是不够的,因此它们不是合适的选择。
例如,我有一个名为IDataline的'Dataline'的接口类。 IDataLine接口的实现在构造时采用分隔字符串,对其进行解析并公开字段列表。通过具有forward_iterator_tag语义的const_iterator。 没有STL容器可以开箱即用。
此外,我的客户端类希望能够遍历两个数据行字段并逐字段地比较它们。
我已经定义了IDataline接口,如下所示:
1 class IDataline
2 {
3 public:
4 class const_iterator
5 {
6 public:
7 virtual const_iterator& operator=(const const_iterator& rhs) =0;
8 virtual bool operator==(const const_iterator& rhs) =0;
9 virtual bool operator!=(const const_iterator& rhs) =0;
10 virtual const_iterator& operator++() =0;
11 virtual const_iterator operator++(int) =0;
12 virtual const Field& operator*() =0;
13 virtual const Field* operator->() =0;
14 virtual const Field& operator[](size_t idx) =0;
15 virtual size_t offset() =0;
16 };
17
18 virtual const_iterator begin() =0;
19 virtual const_iterator end() = 0;
20 };
问题可以在第11,18和19行看到 - 我们需要能够返回一个const_iterator,它需要一个复制构造函数,但由于它是虚拟的,所以既没有默认也没有复制构造函数(对于接口类型)和编译器(正确)balks。
你可能会说我可以将begin()和end()定义为:
virtual const_iterator& begin() = 0;
virtual const_iterator& end() = 0;
然后,我可以在专用主机中创建两个专用迭代器实例并返回引用(或指向那些喜欢它们的指针),以使其适合我的情况。
问题是这样的实现不能满足前向迭代器的所有要求,并且会破坏依赖于前向迭代器语义的更一般的用例。
经过一番思考(以及同事咨询),我发现有两种方法可以解决这个问题:
您的寄宿家庭类必须完全抽象吗?如果您可以将抽象最小化到您需要改变的行为,那么您的可实例化主机可以嵌入一个具体的迭代器(因为类本身的实例可以实例化)并且您拥有所需的内容。
Eduardo Leon 表明迭代器本身可以使用pimpl(指向实现的指针)成语来包装。虽然有很多材料可以完整地描述这种技术, Basilev ,在 Leon的建议中的评论中表明他不相信pimpl成语会起作用。我的同事向我提供了一种尝试的技术,因此我将研究一个经过测试的样本。如果它有效,我会分享它。如果没有,我会详细说明样本中获得的经验,并等待更有知识的人来判断pimpl是否适用于这种情况。