gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-10-31 01:21:17 25 4
gpt4 key购买 nike

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

这个问题的解决方案似乎是 Using Iterators to hide internal container and achieve generic operation over a base container .但是,我不明白为什么 begin() 和 end() 成员不再是虚拟的。除此之外,我无法弄清楚 STL 迭代器类(如 operator++、operator* 等)的必要方法到底应该在哪里实现。

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

我的类(class)设计:

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;
};

我想以 STL 样式访问我的网格容器,例如:

GridDataStructure<int>::iterator = someGrid->begin(); // where someGrid is an instance of GridDataUniform
std::cout << *(iter) << std::endl;

非常感谢任何帮助。

编辑 (19.10.10):添加了嵌套迭代器类

编辑 (20.10.10):添加代码:

template<class T>
class GridDataStructureBase
{
protected:
class BaseIteratorImpl
{
virtual iterator begin() = 0;
virtual iterator end() = 0;
virtual iterator& operator++() = 0;
}

public:
class iterator : std::iterator<std::forward_iterator_tag, T>
{
public:
iterator(const BaseIteratorImpl& itImpl) {}
iterator begin() { return itImpl->begin(); }
iterator end() { return itImpl->end(); }
iterator& operator++() { return itImpl->operator++() }

private:
BaseIteratorImpl* itImpl;

};

iterator begin()
{
iterator* i = new iterator(??);
return i->begin();
}

iterator end()
{
return iterator(NULL);
}

};

最佳答案

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

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

编辑:这里有一些东西可以开始(未经测试甚至编译)——可能无法编译并且会泄漏(编写析构函数、复制 ctors、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;
};

我直接将其输入到此答案的文本区域——而不是编译器。它旨在为您提供想法,以便您可以开始。

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

关于c++ - 快速灵活的抽象类迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3960948/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com