问题描述
我有一个自定义容器,它以两种不同的方式实现,但只有一个接口.像这样的东西.
I've a custom container which is implemented in two different ways, but with a single interface. some thing like this.
class Vector
{
virtual Iterator begin() = 0;
virtual Iterator end () = 0 ;
... // some more functions.
} ;
class VectorImplA : public Vector
{
Iterator begin() { return m_data.begin() ; }
Iterator end () { return m_data.end() ; }
private:
SomeFloatContainer m_data ;
} ;
class VectorImplB : public Vector
{
Iterator begin() { return m_data.end() ; }
Iterator end() ; { return m_data.end() ; }
private:
std::vector <float> m_data ;
} ;
我需要的是一个统一的Iterator接口,这样我就可以在基类中使用它.有什么想法吗?
What I need is a unified interface to Iterator, so that I'can use it in base class. Any Ideas ?
推荐答案
我自己以前也遇到过这个问题.虽然有一些方法可以解决您的问题,但您很可能应该放弃向量基类的想法.相反,您可能应该做的是模仿 c++ STL 容器的设计方式.
I've run into exactly this problem myself before. While there are ways to solve your problem, you most likely should let go of the idea of a vector base class. What you probably should do instead, is mimic the way the c++ STL container are designed.
STL 由概念而不是基类组成.std::vector
是 Container
概念的模型,但不继承自 Container
基类.概念是概念的任何模型都应遵守的一组要求.请参阅 this 页面了解 Container
的要求例子.
The STL consists of concepts rather than base classes. An std::vector
is a model of the Container
concept, but does not inherit from a Container
base class. A concept is a set of requirements that any model of the concept should adhere to. See this page for the requirements for Container
for example.
Container
的要求规定,例如你应该 typedef 容器内容的类型为 value_type
,typedef 迭代器为 iterator
和 const_iterator
.此外,您应该定义返回迭代器的 begin()
和 end()
函数,等等.
The requirements for Container
state for example that you should typedef the type of the contents of the container as value_type
, and typedef iterators as iterator
and const_iterator
. Furthermore, you should define begin()
and end()
functions returning iterators, and so on.
然后,您需要更改在 Vector
基类上运行的函数,以改为在任何符合该概念强加要求的类上运行.这可以通过使函数模板化来完成.您不一定要坚持 STL 使用的概念,您不妨自己编写.坚持 STL 中定义的概念还有一个额外的好处,那就是 STL 算法(例如 std::sort
)可以在您的容器上运行.
You'll then need to change functions that operate on your Vector
base class to instead operate on any class that adheres to the requirements imposed by the concept. This can be done by making the functions templated. You don't necessarily have to stick to the concepts used by the STL, you might as well cook up your own. Sticking to the concepts as they are defined in the STL has the additional benefit that the STL algorithms (std::sort
for example) can operate on your containers.
快速示例:
class VectorImplA
{
public:
typedef VectorImplAIterator iterator;
iterator begin();
iterator end();
};
class VectorImplB
{
public:
typedef VectorImplBIterator iterator;
iterator begin();
iterator end();
};
template <typename VectorConcept>
void doSomeOperations(VectorConcept &container)
{
VectorConcept::iterator it;
it = container.begin();
}
int main()
{
VectorImplA vecA;
VectorImplB vecB;
doSomeOperations(vecA); // Compiles!
doSomeOperations(vecB); // Compiles as well!
}
作为奖励,要回答最初的问题,请考虑以下设计(不过我不会这样做!):
As a bonus, to answer the original question, consider the following design (I wouldn't go this way though!):
struct IteratorBase
{
virtual void next() = 0;
};
struct IteratorA : IteratorBase
{
void next() {};
};
struct IteratorB : IteratorBase
{
void next() {};
};
class Iterator
{
IteratorBase *d_base;
public:
void next() { d_base->next(); }
};
这篇关于具有派生类的自定义容器的迭代器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!