【发布时间】:2011-01-31 15:32:54
【问题描述】:
我正在尝试在 C++ 中实现多态迭代器。基本上,我需要它才能应用过滤器,以便迭代器根据相关条件跳过一些项目。所以我创建了一个带有抽象接口的GoF-like 迭代器,这允许我从中派生一个过滤的迭代器并实现所需的逻辑。我也更喜欢基于接口的迭代器而不是模板迭代器,因为它们允许隐藏实现而不会导致混乱的鸭子类型模板。
但是,多态迭代器不能按值返回(与 STL 迭代器相反),所以我必须传递指针,这很容易变得像这种情况一样危险,这似乎合乎逻辑但会导致内存泄漏:
Iter* Collection::GetIter() {...} // new IterImpl
DoSomething(Iter*) {...} // doesn't do delete
DoSomething(Collection.GetIter()); // convenient, but wrong :\
显而易见的解决方案是使用某种智能指针来控制迭代器的生命周期,但人们常说接口应该尽可能简单和通用,所以应该避免智能指针?
如果您在 C++ 中使用过多态迭代器,这个问题是如何解决的?还是基于模板的迭代器是 C++ 中唯一“好”的迭代方式?谢谢。
【问题讨论】:
-
您可以很容易地在 C++ 中实现过滤迭代器,而不会暴露任何外部多态性(Boost 提供 a generic filter iterator)。
-
@7vies:Matthie M 对该问题的回答使用了智能指针,但作为实现细节,不在接口中。所以我认为你对简单/通用接口的反对并不适用。顺便说一句,如果您更喜欢多态迭代器而不是使用模板进行鸭式打字,我可以推荐 Java 吗? ;-p
-
@7vies:它存在,但是 STL 强制执行了非常严格的迭代器模型,与 GOF 模型完全不兼容:/
-
@7vies:如果你想要mark-sweep GC,那么我可以推荐Java吗?或者你可以试试 Boehm 的 C++ GC。 C++ 迭代器是用值语义设计的,Matthieu 对另一个问题的回答是在值语义和运行时多态性之间架起桥梁的“正确”习语。在这种情况下,智能指针完全按照需要管理分配的资源。我真的不知道“跛脚”应该是什么意思——智能指针可以很好地处理这种情况。那么有什么问题呢?
-
@7vies:“如果我不打算在容器上使用 STL 算法,为什么还要对容器使用 STL 迭代器?”——您不必使用 STL 迭代器。但是你说你要按值返回,这意味着你必须实现值语义。顺便说一句,这意味着使用
shared_ptr而不是unique_ptr,这样它是可复制的,如果你从马蒂厄的回答开始的话。
标签: c++ iterator polymorphism