首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将DRY原则应用于C++中的迭代器?(迭代器、const_iterator、reverse_iterator、const_reverse_iterator)

如何将DRY原则应用于C++中的迭代器?(迭代器、const_iterator、reverse_iterator、const_reverse_iterator)
EN

Stack Overflow用户
提问于 2009-11-22 04:17:09
回答 6查看 1.2K关注 0票数 5

好了,我现在有两个使用迭代器的类(完全无关,不同的项目)。一个具有预期的iteratorreverse_iterator,另一个具有iterator和半中断的const_iterator (具体地说,因为const_iterator派生自迭代器,所以代码LinkedList<int>::iterator i = const_list.begin()是有效的,并允许您修改const定义的列表...)。

我打算将所有四种类型都添加到这个类中。如果可以的话。

我如何继续最小化复制/粘贴代码并只更改返回类型?创建一个像base_iterator这样的基类来继承吗?创建一个iteratorconst_iterator并继承它?继承自某个std::class?如果这些情况中的任何一种都是“最好的”方法,那么什么代码会去哪里呢?

也许没有一种替代方案是好的?我在这里完全迷路了,找不到太多的参考资料。

感谢任何建议,但请记住,我对这个主题(迭代器和C++,尤其是OOP)还是个新手。我试着研究了GCC附带的头文件,但徒劳无功--它们并不是我要找的教程。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2009-11-22 04:22:28

有时,全面应用所谓的DRY规则(对于那些不熟悉的人来说是Don't Repeat Yourself)并不是最好的方法。特别是如果你是语言(C++和迭代器)和OOP本身(方法论)的新手,那么现在尽量减少你需要编写的代码量是没有什么好处的。

我将使用适当的代码来实现这两个迭代器。也许在您对语言、工具和技术有了更多的经验之后,再回头看看是否可以通过分解公共代码来减少代码量。

票数 3
EN

Stack Overflow用户

发布于 2009-11-23 16:15:16

这实际上非常简单。

首先,看看Boost.Iterator库。

其次:您需要声明一个基类(在示例中已经很好地解释了如何继续),它将类似于这个基类。

代码语言:javascript
运行
复制
template <class Value>
class BaseIterator: boost::iterator_adaptor< ... > {};

你实现了在那里移动指针的操作。请注意,因为它是对现有迭代器的改编,所以您只需几个笔画就可以实现它。这真的很令人印象深刻。

第三,您只需使用const和非const版本来定义它:

代码语言:javascript
运行
复制
typedef BaseIterator<Value> iterator;
typedef BaseIterator<const Value> const_iterator;

该库明确地向您展示了如何从iterator版本构建const_iterator版本。

第四,与之相反的是,有一个特殊的reverse_iterator对象,它构建在常规迭代器上并向后移动:)

总而言之,这是一种在自定义类上定义迭代器的非常优雅且功能齐全的方法。

我经常编写自己的容器适配器,与其说是干,不如说是省去了一些打字工作!

票数 3
EN

Stack Overflow用户

发布于 2009-11-22 05:19:48

使迭代器从const_iterator派生,而不是反过来派生。适当地使用const_cast (作为实现细节,不向用户公开)。这在“迭代器直接是const_iterators”的简单情况和模型中工作得很好。

当这开始需要代码中的澄清注释时,请编写单独的类。您可以使用本地化的宏为您生成类似的代码,以避免重复逻辑:

代码语言:javascript
运行
复制
struct Container {
#define G(This) \
This& operator++() { ++_internal_member; return *this; } \
This operator++(int) { This copy (*this); ++*this; return copy; }

  struct iterator {
    G(iterator)
  };
  struct const_iterator {
    G(const_iterator)
    const_iterator(iterator); // and other const_iterator specific code
  };
#undef G
};

宏的作用域/本地化很重要,当然,只有在它确实对您有帮助的情况下才使用它-如果它导致代码的可读性较差,请显式地键入它。

关于反向迭代器:在许多情况下,您可以使用std::reverse_iterator包装您的“常规”迭代器,而不是重写它们。

代码语言:javascript
运行
复制
struct Container {
  struct iterator {/*...*/};
  struct const_iterator {/*...*/};

  typedef std::reverse_iterator<iterator> reverse_iterator;
  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
};
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1776641

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档