我想设计一个抽象的Dataset
类。派生类在存储数据和迭代方面有所不同。以下是一些派生类示例:
InMemoryDataset
:将所有数据存储在内存中vector<Row>
StreamingTextDataset
:不会将数据存储在内存中,也可以从文本文件中传输行。StreamingBinaryDataset
:也不会将数据存储在内存中,而是从二进制文件中流式传输行(如果需要,可以按随机顺序提供示例)。这是我目前的设计,但我觉得它很尴尬,因为它不是严格抽象的(即它没有任何虚函数)。派生类通过派生Dataset
类并使用正确的State
对象初始化state_
变量来扩展此State
。
是否有比这更简洁/更简单的设计?
class Dataset {
protected:
class State {
public:
virtual ~State() {}
virtual void Reset() = 0;
virtual bool MoveNext() = 0;
virtual const Row* Current() const = 0;
};
std::unique_ptr<State> state_;
public:
struct Iterator {
Iterator(State *state);
const Row& operator*() const;
const Row* operator->() const;
Iterator operator++();
bool operator!=(const Iterator & other);
private:
State *state_;
};
Iterator begin() const;
Iterator end() const;
};
答案 0 :(得分:0)
从你到现在为止,它似乎只是Range concept的封装。
您希望能够遍历行
有不同类型的范围
迭代可能是有状态的
我不确定你需要自己的类层次结构而不是迭代器本身的内部多态性。问题是如何做到这一点。
如果您可以使用编译时多态性,可以使用boost::iterator_range
template<typename Iterator>
class Dataset :
public boost::iterator_range<Iterator>
...
并使用各种迭代器(可能使用std::istream_iterator
,使用说boost::iterator_facade
或任意组合的自定义迭代器)实例化它。
如果你必须具有运行时多态性,那么你只需要type erasure。我只想使用boost::iterator_facade
和boost::any
构建自定义迭代器。