简体   繁体   English

cpp迭代器继承

[英]cpp iterator inheritance

My requirements are same to the question asked Using Iterators to hide internal container and achieve generic operation over a base container [ 1 ] at stackoverflow. 我的要求与使用迭代器隐藏内部容器并在stackoverflow 上通过基本容器 [ 1 ] 实现泛型操作的问题相同。 I have a generic pure virtual base container class, which needs to provide an iterator which should be STL complaint so I can use them with cpp algorithm's #include <algorithm> . 我有一个通用的纯虚拟基础容器类,它需要提供一个应该是STL投诉的迭代器,所以我可以使用它们与cpp算法的#include <algorithm> My implementation uses only an single class instead of two classes as in [ 1 ] solution. 我的实现仅使用单个类而不是[ 1 ]解决方案中的两个类。

Base pure virtual class 基础纯虚拟类

class BaseItr
{
  public:
    class iterator : public std::iterator<std::input_iterator_tag, int>
    {
      public:
        iterator() : _in(NULL) {}
        inline iterator(const iterator& org) : _in(org._in) {}
        inline iterator& operator=(const iterator& other) { _in = other._in; return *this; }
        virtual inline int operator * () { return _in->operator*(); }
        virtual inline iterator& operator++() { (*_in)++; return *this; }
        virtual inline iterator& operator++(int unused) { (*_in)++; return *this; }
        virtual inline bool operator==(const iterator& other) 
        {
          return *(*_in) == *(*(other._in));
        }
        virtual inline bool operator!=(const iterator& other)
        {
          return *(*_in) != *(*(other._in));
        }
        // would use shared pointer insted of this
        //~iterator() { if(_in) { delete _in; } }
        static inline iterator New(iterator *in) { return iterator(in); }
      private:
        iterator(iterator *in) : _in(in) {}
        iterator *_in;
    };

    virtual iterator begin() = 0;
    virtual iterator end() = 0;
};

Implementation 履行

class Itr : public BaseItr
{
  private:
    class iterator : public BaseItr::iterator
    {
      public:
        iterator(int val) : _val(val), BaseItr::iterator() {}
        int operator * () { return _val; }
        inline iterator& operator++() { ++_val; return *this; }
        inline iterator& operator++(int unused) { _val++; return *this; }
      private:
        int _val;
    };
    BaseItr::iterator _begin;
    BaseItr::iterator _end;
  public:
    inline Itr(int start, int end)
    {
      _begin = BaseItr::iterator::New(new iterator(start));
      _end = BaseItr::iterator::New(new iterator(end));
    }

    BaseItr::iterator begin() { return _begin; }
    BaseItr::iterator end() { return _end; }
};

My implementation works was need, I want to know are there any drawbacks with this implementation, Please help me decide with my design to use the appropriate implementation. 我的实现工作是需要的,我想知道这个实现有什么缺点,请帮我决定使用我的设计来使用适当的实现。 I have add my full working example code in github:gist https://gist.github.com/3847688 我在github中添加了我的完整工作示例代码:gist https://gist.github.com/3847688

Ref: 参考:

The most glaring issue: your iterator does not have value semantics. 最明显的问题:你的迭代器没有值语义。

The STL algorithms are free to copy an iterator if they wish. 如果愿意,STL算法可以自由地复制迭代器。 For example suppose: 比如假设:

template <typename It>
It find(It b, It e, typename std::iterator_traits<It>::const_reference t) {
    for (; b != e; ++b) {
        if (*b == t) { return b; }
    }
    return e;
}

The problem is that if you invoke this algorithm with BaseItr& , then the result is of type BaseItr , and you are thus exposed to Object Slicing , which is undefined behavior . 问题是,如果使用BaseItr&调用此算法,则结果为BaseItr类型,因此您将暴露于对象切片 ,这是未定义的行为

In order to give value semantics to you iterator, you need to create a wrapper class around an abstract implementation and have the wrapper correctly manage the copy through a virtual clone method. 为了给迭代器赋予值语义,您需要围绕抽象实现创建一个包装类,并让包装器通过虚拟clone方法正确地管理副本。 If your iterator ends up with virtual methods, you are doing it wrong. 如果您的迭代器最终使用虚方法,那么您做错了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM