在c++中,可迭代类型应该是非多态的

In C++, should iterable types be non-polymorphic?

本文关键字:是非 多态 类型 迭代 c++      更新时间:2023-10-16

背景:

我目前正在做一项面向对象课程的作业,它包括围绕各种设计模式设计和实现一个电话簿管理器。

在我的项目中,所有的动作都围绕着3个类发生:

  • PhoneBook;
  • Contact(存储在电话簿中的类型);
  • ContactField (Contact中存储的字段).

ContactManager必须提供一种方法,在两种模式下迭代它的联系人:基于谓词的未过滤和过滤;Contact必须提供一种遍历其字段的方法。

我最初是如何决定实现的:

我遇到的所有设计模式书籍都建议对接口进行编码,所以我的第一个想法是从上面的每个类中提取一个接口,然后让它们实现它。

现在我还必须创建某种多态迭代器,以便事情顺利进行,因此我调整了Java迭代器接口来编写前向迭代器。

问题:

  • 这种设计的主要缺点是失去了互操作性使用stl <algorithm>和range提供的语法糖

  • 我遇到的另一个问题是Iterator<T>::remove()函数。如果我想要一个可以改变迭代序列的迭代器(删除元素)然后一切都很好,但如果我不想我不知道该怎么做。

    我看到在Java中可以抛出UnsupportedOperationException这并不是那么糟糕,因为(如果我说错了请纠正我)如果异常未处理,则终止应用程序,并显示堆栈跟踪。在c++中,没有这种奢侈(除非你运行附带调试器我认为),说实话我宁愿在编译时捕获这些错误。


(在我看来)解决这种混乱的最简单方法是避免在可迭代类型上使用接口,以便适应我自己的仍然兼容的迭代器。这将增加耦合,但我不确定从长远来看它是否会有任何影响(当然,这并不是说这个项目很快就会变成扔掉的代码)。我的猜测是不会的,然而,在我继续我的设计之前,我也想听听长辈们的意见。

我可能会采取稍微不同的方法。

首先,对联系人的迭代非常简单,因为它是单一类型的迭代,您可以提供beginend方法来允许对底层字段进行迭代。

对于PhoneBook的迭代,我将仍然只是提供一个正常的beginend,然后提供一个for_each_if函数,您使用它只迭代感兴趣的联系人,而不是试图提供一个超自定义迭代器,跳过不感兴趣的元素。