我正在尝试实现以下目标:给定一个抽象类MemoryObject,每个类都可以继承该类,我有两个子类:Buffer和BigBuffer:
template <typename T>
class MemoryObject
{
public:
typedef typename std::vector<T>::iterator iterator;
typedef typename std::vector<T>::const_iterator const_iterator;
[...] //Lot of stuff
virtual iterator begin() = 0;
virtual iterator end() = 0;
};
缓冲区:
template <typename T>
class Buffer: public MemoryObject<T>
{
public:
typedef typename std::vector<T>::iterator iterator;
iterator begin() { return buffer_.begin(); }
iterator end() { return buffer_.end(); };
[...] //Lot of stuff
private:
std::vector<T> buffer_;
};
最后:
template <typename T>
class BigBuffer: public MemoryObject<T>
{
public:
[...] //Omitted, for now
private:
std::vector<Buffer<T>*> chunks_;
};
如您所见,BigBuffer持有Buffer *的std::vector,因此您可以将BigBuffer视为Buffer的集合。此外,我有一堆必须对每个MemoryObject起作用的函数,因此这是一个真实的签名:
template <class KernelType, typename T>
void fill(CommandQueue<KernelType>& queue, MemoryObject<T>& obj, const T& value)
{
//Do something with obj
}
重点是什么? -你可能会问。关键是我必须在这些类上实现迭代器。我已经为Buffer实现了它们,而这正是我所需要的:能够迭代Buffer并访问范围(例如b.begin(),b.begin()+ 50)。
显然,我对BigBuffer不能这样做,因为真实数据(在每个Buffer的私有(private)变量buffer_内部)分散在整个内存中。因此,我需要一个新类,我们将其称为BigBufferIterator,它可以使*或+之类的运算符重载,从而使我可以从一个内存块“跳转”到另一个内存块而不会引起分段错误。
问题有两个:
BigBuffer的类型:前者是std::vector ::iterator,
后者是BigBufferIterator。我的编译器显然抱怨
仅将MemoryObject &传递给他们,而不专用于
每个类类型。
我试图解决第一个问题,即添加一个模板参数类Iterator,并为每个类提供默认参数,并使用一个基于Alexandrescu基于策略的模型的松散模型。此解决方案解决了第一个问题,但没有解决第二个问题:当我尝试将BigBuffer传递给函数(例如fill())时,我的编译器仍然抱怨说:“从BigBuffer到MemoryObject的未知转换”。这是因为迭代器类型不同。
我为这首诗感到非常抱歉,但这是向您正确表达我的问题的唯一方法。我不知道为什么有人甚至不愿意阅读所有这些东西,但是我会倒霉的。
在此先感谢您,直到此处为止。
谦虚
阿尔弗雷多
最佳答案
他们要走的路是使用最通用的定义作为基础的迭代器类型。也就是说,您希望将Buffer
中的数据视为一个片段,而BigBuffer
是相应片段的序列。这有点不幸,因为这意味着您将Buffer
中的单个缓冲区的迭代器视为可能是多个缓冲区,即,您的分段结构只有一个段。但是,与替代方案相比(即,迭代器的层次结构具有由句柄包装的虚函数,为该困惑提供了值语义),实际上您并没有为此付出代价。
关于c++ - C++:在子类中使用不同的迭代器类型而不破坏继承机制,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9239489/