使用迭代器来隐藏内部容器并实现基本容器上的通用操作 [英] Using Iterators to hide internal container and achieve generic operation over a base container

查看:242
本文介绍了使用迭代器来隐藏内部容器并实现基本容器上的通用操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我基本上想要一个基础容器类,它可以返回一个通用的迭代器,可以用来遍历一个容器类的实例,而不需要指定迭代器模板。我想我不能实现基类容器在类模板,这将需要一个基于模板类的预先不知道的遍历算法。基本容器可以使用其中的任何(自定义或标准)容器类型/实现来继承和实现。下面是一些代码示例,以使它清楚:

I basically want to have a base container class which can return a generic iterator that can be used to traverse an instance of the container class, without needing to specify iterator templates. I think I cannot implement the base container over a class template, which would then require a traversal algorithm based on template classes which are not known in advance. The base container can be inherited and implemented using any (custom or standard) container type/implementation within. Here are some code samples to make it clear:

struct MyObject {
  int myInt;
}

// an abstract container
class BaseContainer {
public:
  virtual void insertMyObject(MyObject& obj) = 0;
  virtual iterator getFirst(); // the iterator type is for demonstration purposes only
  virtual iterator getLast();  // the iterator type is for demonstration purposes only
}

// Sample container class that uses a std::vector instance to manage objects
class BaseContainer_Vector : public BaseContainer {
public:
  void insertMyObject(MyObject& obj); // e.g. just pushes back to the vector
  iterator getFirst(); // needs to override the iterator?
  iterator getLast();  // needs to override the iterator?
private:
  std::vector<MyObject> objectContainer;
}

然后我将有一个容器对象列表,这些容器和对象都存储。

I will then have a list of container objects, and I want to iterate over both these containers and the objects stored.

std::vector<MyContainer*> containers;
for(int i=0 ; i<containers.size() ; i++){
  iterator i    = containers[i]->getFirst();
  iterator iend = containers[i]->getLast();
  for(; i != iend ; i++) {
    std::cout << (*i).myInt << std::endl;
  }
}

我还想支持boost foreach宏声明。它支持扩展,只要range_begin和range_end函数正确。但是,boost doc中的示例使用std :: string :: iterator作为返回类型,而我需要的是一个通用的迭代器类,我还不知道如何做到这一点。

I further would like to have support for boost foreach macro statement. It supports extensions as long as range_begin and range_end functions are properly. But, the example in boost doc uses std::string::iterator as return type, while what I need is a generic iterator class and I could not yet figure out how to do that as well.

std::vector<MyContainer*> containers;
for(int i=0 ; i<containers.size() ; i++){
  BOOST_FOREACH(MyObject obj, *(containers[i])) {
    std::cout << obj.myInt << std::endl;
  }
}



我想我可以定义自己的迭代器类,然后每个扩展BaseContainer的类都应该定义自己的迭代器来扩展这个基本迭代器。然而,我更喜欢使用标准迭代器(stl或boost)来支持这种结构,而不是编写自己的迭代器。我想这种方法会工作,但我可以对其效率的意见。

I think I can define my own iterator class, then each class that extends BaseContainer should define their own iterator extending that basic iterator. Yet, I would prefer to use standard iterators (stl or boost) to support this structure, rather that writing my own iterators. I guess this approach will work, but I am open to comments regarding its efficiency.

有一个可行的方法可以解决这个问题优雅吗?或者我缺少一个简单的点,可以解决这个问题没有任何痛苦?

Is there a feasible approach that can solve this problem elegantly? Or am I missing a simple point which can solve this problem without any pain?

可以找到类似的问题

A similar question can be found here, but the proposed solutions seem a bit complex for my needs, and the requirements differ as far as I can understand.

推荐答案

这将是复杂的。

如前所述,因为它们通常被复制,否则会导致对象切片。

As already stated, first you need your iterators to have value semantic because since they are usually copied around otherwise it would result in object slicing.

class BaseContainer
{
protected:
  class BaseIteratorImpl; // Abstract class, for the interface

public:
  class iterator
  {
  public:
    iterator(const BaseIteratorImpl& impl);
  private:
    BaseIteratorImpl* m_impl;
  };

  iterator begin();
  iterator end();
}; // BaseContainer

然后, BaseIterator m_impl 的方法。

这样就可以用多态核实现价值语义语法。

This way you achieve value semantic syntax with a polymorphic core.

显然,你必须处理deep-copy语义和正确的销毁。

Obviously, you'll have to handle deep-copy semantics and proper destruction.

一些注释:


  • 发布迭代器 const_iterator / li>
  • 命名您的方法 empty size begin
  • publish both an iterator and a const_iterator class
  • name your methods empty, size, begin, end etc... for compatibility with STL algorithms

您可以检查 SGI迭代器,了解有关概念和操作的帮助运营商应该支持最大的兼容性。

You can check SGI Iterators for help about the Concepts and operations your operators should support for maximum compatibility.

这篇关于使用迭代器来隐藏内部容器并实现基本容器上的通用操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆