4

除了迭代器概念所需的常规方法之外,是否有任何理由不在迭代器中包含非标准方法?附加方法将特定于迭代器生成的项目类型。


具体例子

为了使我的问题更具体,我正在对 GUI 菜单中的菜单项进行交互。在内部,迭代器通过索引访问菜单。取消引用时,它会在该索引处查询该项目的菜单,创建一个表示菜单返回的属性的不可变对象,并将其缓存在成员变量中,然后返回对它的引用。

不安全的解决方案

另一种方法是使表示可变并使其将属性更新写回底层菜单。它看起来像这样:

menu m = some_menu();
menu_iterator pos = m.begin() + 3;

menu_item i = *pos;
...
i.caption("foo");
i.disable();

这意味着每个menu_item表示都必须存储它的位置和菜单句柄——没什么大不了的——除非菜单在创建项目表示后已经插入/删除了一个项目。在这种情况下,随着完全不同的项目的属性发生变化,各种地狱都可能会崩溃。

更好的解决方案?

所以我的想法是添加额外的方法来改变迭代器的属性而不是它返回的值。这样,用户总是知道正在更新的是当前指向的项目,并且插入使其无效的通常迭代器语义适用(它不会真正使其无效,它只会指向不同的项目)。

menu m = some_menu();
menu_iterator pos = m.begin()+3;
...
pos.caption("foo");
pos.disable();

你怎么看?

4

2 回答 2

1

这是我要做的:

  • 如果您不需要能够通过迭代器改变菜单项,只需设置menu_item不可变 - 问题就解决了。
  • 如果您需要能够通过迭代器改变菜单项:
    • 如果您对底层菜单实现具有这种类型的控制,请menu_item指向实际的菜单对象,该对象在添加新菜单项时不会失效。您甚至可以让迭代器在取消引用时返回(当然是通过引用)实际的菜单对象并menu_item完全取消包装器。
    • 如果您没有那种类型的控件,那么menu_item它实际上是菜单项的代理,而不是菜单项本身。调用它menu_item_proxy,并记录它具有代理行为,并且当迭代器失效时代理也会失效。用户仍然可以使用语法“在迭代器上”调用方法pos->caption("foo")

我不会将方法caption()放在迭代器本身内部。(例如,如何使用它们for_each?)

于 2012-05-29T02:52:36.720 回答
-1

向迭代器添加方法并没有错。迭代器只是访问者的一个特例。访问者应该在访问某个对象时执行所有必需的操作。随意添加您的业务需要的任何方法

于 2012-05-29T20:29:57.637 回答