Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 快速灵活的抽象类迭代器_C++_Stl_Iterator - Fatal编程技术网

C++ 快速灵活的抽象类迭代器

C++ 快速灵活的抽象类迭代器,c++,stl,iterator,C++,Stl,Iterator,为了以快速灵活的方式使用数据遍历网格,我建立了一个抽象的、模板化的GridDataStructure类。数据应该由STL迭代器访问。当有人使用这个类时,他不应该担心哪种STL迭代器适合特定的子类 解决这个问题的办法似乎是。但是,我不明白为什么begin()和end()成员不再是虚拟的。接下来,我无法确定STL迭代器类(如operator++、operator*等)的必要方法应该在哪里实现 你能看看我是否犯了设计错误吗?对我来说重要的是灵活的设计,但不是以性能为代价 我的课堂设计: templat

为了以快速灵活的方式使用数据遍历网格,我建立了一个抽象的、模板化的GridDataStructure类。数据应该由STL迭代器访问。当有人使用这个类时,他不应该担心哪种STL迭代器适合特定的子类

解决这个问题的办法似乎是。但是,我不明白为什么begin()和end()成员不再是虚拟的。接下来,我无法确定STL迭代器类(如operator++、operator*等)的必要方法应该在哪里实现

你能看看我是否犯了设计错误吗?对我来说重要的是灵活的设计,但不是以性能为代价

我的课堂设计:

template<class T>
class GridDataStructure
{
public:
    virtual iterator begin() = 0;
    virtual iterator end() = 0;
};

template<class T>
class GridDataUniform : GridDataStructure
{
public:
    GridDataUniform(int size);        

    iterator begin();
    iterator end();

    class iterator : public std::iterator<std::forward_iterator_tag, T> {
    public:
      iterator(Node* p) : node_(p) {}
      ~iterator() {}

      iterator& operator=(const iterator& other);
      bool operator==(const iterator& other);
      bool operator!=(const iterator& other);
      iterator& operator++();
      iterator& operator++(int);
      T& operator*();
      T* operator->();

    private:
      Node* node_;
    };

    private:
        T* griddata;
};
模板
类GridDataStructure
{
公众:
虚拟迭代器begin()=0;
虚拟迭代器end()=0;
};
模板
类GridDataUniform:GridDataStructure
{
公众:
GridDataUniform(整数大小);
迭代器begin();
迭代器end();
类迭代器:public std::iterator{
公众:
迭代器(Node*p):Node_u(p){}
~iterator(){}
迭代器和运算符=(常量迭代器和其他);
布尔运算符==(常量迭代器和其他);
布尔运算符!=(常量迭代器和其他);
迭代器和运算符++();
迭代器和运算符++(int);
T&算子*();
T*运算符->();
私人:
Node*Node_;
};
私人:
T*griddata;
};
我想以STL样式访问我的网格容器,如:

GridDataStructure<int>::iterator = someGrid->begin(); // where someGrid is an instance of GridDataUniform
std::cout << *(iter) << std::endl;
GridDataStructure::iterator=someGrid->begin();//其中someGrid是GridDataUniform的一个实例
std::cout end();}
迭代器和运算符++(){return itImpl->operator++()}
私人:
BaseIteratorImpl*itImpl;
};
迭代器begin()
{
迭代器*i=新迭代器(??);
返回i->begin();
}
迭代器结束()
{
返回迭代器(NULL);
}
};

在解决方案中,begin和end不需要是虚拟的,因为它们只调用
BaseIteratorImpl::begin
BaseIteratorImpl::end
,它们是虚拟的

在您的特定情况下,您可以只将
开始
结束
设置为虚拟,而不进行任何转发,这样它就可以执行您想要的操作。您所指的解决方案是,如果您希望在同一结构上使用不同样式的迭代器,而不仅仅是您希望的结构迭代器对

编辑:这里有一个开始(未经测试,甚至未编译)——可能不会编译并且会泄漏(写入析构函数、复制析构函数、op=,在需要的地方)——只是为了让您开始了解这个想法

template <class T>
class GridIteratorImplBase {
   public:
      virtual GridIteratorImplBase<T>& operator++() = 0;
      virtual T& operator*() = 0;
};

template <class T>
class GridIterator {
   private:
      GridIteratorImplBase<T> *baseImpl;
   public:
      GridIterator(GridIteratorImplBase<T> *b) :baseImpl(b) {}
      GridIterator& operator++() { baseImpl->operator++(); return *this;}
      T& operator*() { return baseImpl->operator*(); }


  // you need to write a dtor, copy ctor and op= or this will leak
  // copy ctor and op= need to make new objects that are copies of baseImpl, dtor needs to delete -- make sure not to share baseImpl between two GridIterator objects
};


template <class T>
class Grid {
   virtual GridIterator<T> begin() = 0;
   virtual GridIterator<T> end() = 0;
};


template <class T>
class GridUniform {

  template <class T>
  class GridUniformIterator : GridIteratorImplBase<T>
      private T* current;
   public:
      GridUniformIterator(T* c) : current(c) {}
      virtual GridIteratorImplBase<T>& operator++() { current++; return *this; }
      virtual T& operator*() { return *current; }
  };

  GridIterator<T> begin() { 
      GridIterator<T> iter(new GridUniformIterator(gridData)); 
      return iter; 
  }
  GridIterator<T> end() { 
      GridIterator<T> iter(new GridUniformIterator(gridData+size));
      return iter; 
  }


  private:
    T* gridData;
    int size;
};
模板
类GridIteratorImplBase{
公众:
虚拟网格迭代器mplbase&operator++()=0;
虚拟T运算符*()=0;
};
模板
类网格迭代器{
私人:
GridIteratorImplBase*baseImpl;
公众:
GridIterator(GridIteratorImplBase*b):baseImpl(b){}
GridIterator&operator++(){baseImpl->operator++();返回*this;}
运算符*(){return baseImpl->operator*();}
//你需要写一个dtor,复制ctor和op=否则就会泄漏
//copy ctor和op=需要创建新对象,这些对象是baseImpl的副本,dtor需要删除--确保不要在两个GridIterator对象之间共享baseImpl
};
模板
类网格{
虚拟网格迭代器begin()=0;
虚拟网格迭代器end()=0;
};
模板
班级制服{
模板
类GridUniformator:GridIteratorImplBase
私人T*电流;
公众:
网格均匀化器(T*c):电流(c){
VirtualGridIteratorImplBase&operator++(){current++;return*this;}
虚拟T运算符*(){return*current;}
};
GridIterator begin(){
网格迭代器iter(新网格均匀迭代器(gridData));
返回iter;
}
GridIterator end(){
网格迭代器iter(新的网格均匀迭代器(gridData+size));
返回iter;
}
私人:
T*gridData;
整数大小;
};
我直接把它输入到这个答案的文本区,而不是编译器。这是为了给你一个想法,这样你就可以开始了

  • 开始和结束应该创建迭代器
  • 迭代器需要能够被复制构造并调用operator=。如果您尝试为它们创建一个基类,它们将被强制转换为基类,因此您不能为它们使用虚拟
  • 为了绕过#2,需要让迭代器只保留一个指向迭代器实现基类的指针

  • 谢谢你明确的回答。我确实误解了BaseIteratorImpl的主要目标。我确实想要结构迭代器对。我将GridDataUniform的迭代器(以及我的其他子类)实现为一个嵌套类(std::iterator的子类),并实现了operator++()和operator*()等方法。但是,我不确定如何以这样的方式构造代码:GridDataStructure::iterator=someGrid->begin();//someGrid是GridDataUniform std::cout的实例,您可能应该将当前代码添加到问题中,并指出存在问题的部分。我添加了嵌套迭代器类及其方法。希望这能把事情弄清楚?现在我知道你要去哪里了,你需要做一个迭代器,它包含一个iterImpl,就像你提到的问题一样。问题是您的基本容器无法知道返回类型——因此它必须转发到实际类型。这就是我丢失的地方。我应该在GridDataBase中创建一个嵌套的超类,从std::iterator继承它,然后从它继承iterator吗?
    template <class T>
    class GridIteratorImplBase {
       public:
          virtual GridIteratorImplBase<T>& operator++() = 0;
          virtual T& operator*() = 0;
    };
    
    template <class T>
    class GridIterator {
       private:
          GridIteratorImplBase<T> *baseImpl;
       public:
          GridIterator(GridIteratorImplBase<T> *b) :baseImpl(b) {}
          GridIterator& operator++() { baseImpl->operator++(); return *this;}
          T& operator*() { return baseImpl->operator*(); }
    
    
      // you need to write a dtor, copy ctor and op= or this will leak
      // copy ctor and op= need to make new objects that are copies of baseImpl, dtor needs to delete -- make sure not to share baseImpl between two GridIterator objects
    };
    
    
    template <class T>
    class Grid {
       virtual GridIterator<T> begin() = 0;
       virtual GridIterator<T> end() = 0;
    };
    
    
    template <class T>
    class GridUniform {
    
      template <class T>
      class GridUniformIterator : GridIteratorImplBase<T>
          private T* current;
       public:
          GridUniformIterator(T* c) : current(c) {}
          virtual GridIteratorImplBase<T>& operator++() { current++; return *this; }
          virtual T& operator*() { return *current; }
      };
    
      GridIterator<T> begin() { 
          GridIterator<T> iter(new GridUniformIterator(gridData)); 
          return iter; 
      }
      GridIterator<T> end() { 
          GridIterator<T> iter(new GridUniformIterator(gridData+size));
          return iter; 
      }
    
    
      private:
        T* gridData;
        int size;
    };