我对模板的实际使用非常陌生,所以我有以下设计问题。
我正在设计从抽象基类Bunch派生的类Bunch2d和Bunch4d
class Bunch {virtual void create()=0;};
class Bunch2d : public Bunch {void create();};
class Bunch4d : public Bunch {void create();};类Bunch将包含Particle的容器、deque或vector (请参阅this question: Choice of the most performant container (array)):
typedef Blitz::TinyVector<double,DIMENSIONS> Particle;因此,您可以看到我的问题:Bunch必须包含这个容器,因为我的bunch上的“基本”操作是“维度独立的”(例如“容器的大小”、“清除容器”等),所以我认为容器属于基类("Bunch“有一个”容器“)。
但是这个容器必须知道派生类的维度(2或4)。
所以我的想法是使用一个模板化的基类来给typedef提供容器的正确维度:
enum Dimensions {TwoDimensions = 2, FourDimensions = 4, SixDimensions = 6};
template<Dimensions D> class Bunch
{
protected:
typedef Blitz::TinyVector<double,D> Particle;
std::deque<Particle> particles_store;
public:
virtual void create() = 0;
virtual ~Bunch();
};
class Bunch2d : public Bunch<TwoDimensions>
{
public:
~Bunch2d();
void create();
};
class Bunch4d : public Bunch<FourDimensions>
{
public:
~Bunch4d();
void create();
};你能告诉我你对这个设计的意见吗?模板的使用是否正确?那么OO概念的有效性如何呢?使用模板化的基类?
谢谢你的帮助/回答/意见。
发布于 2010-09-06 17:12:49
有一点需要注意:不同的模板实例(即参数中具有不同类型的模板类)具有不同的类型,因此不是单个基类。
如果你需要多态性,你需要在你的设计中添加一个层:
class Bunch
{
public:
virtual void create() = 0;
virtual ~Bunch();
};
template <Dimensions D>
class TBunch: public Bunch
{
private:
typedef Blitz::TinyVector<double,D> Particle;
std::deque<Particle> mParticles;
};
class Bunch2d : public TBunch<TwoDimensions>
{
public:
~Bunch2d();
void create();
};另一个注意事项:属性应该禁止使用protected。
问题是耦合,因为protected将属性/方法暴露给未知数量的类,所以它与public没有什么不同,因为它不可能可靠地声明有多少方法将受到实现更改的影响。
对于方法来说,这是可以接受的,因为方法可以保持向后兼容(有时会以一些技巧/等为代价……但仍然如此)。
对于属性,这是不可接受的,因为属性是实现细节,而不是接口,并且更改不能向后兼容。
因此,我强烈建议您永远不要将protected用于属性。在这种情况下,最好在模板类中分解对mParticles的访问,而不公开底层实现。
小提示:如果您不能在deque和vector之间切换而不破坏包含它们的类之外的内容,那么您就有一个设计问题。
发布于 2010-09-06 17:13:28
这样就失去了让Bunch类的指针在运行时指向Bunch2d或Bunch4d对象的能力,并通过该指针对这些对象进行多态操作。如果对你来说重要的是不要让它松散,不要让基类模板化。否则,在这里使用虚函数和抽象基类就没有任何意义了,所以我建议只使用模板。
发布于 2010-09-06 17:14:06
首先,就继承而言,Bunch<TwoDimensions>和Bunch<FourDimensions>是完全不相关的类。因此,Bunch2d和Bunch4d没有共同的基类!
如果这对你来说是个问题,你将不得不去掉模板化,并在运行时将DIMENSIONS参数化。
https://stackoverflow.com/questions/3650161
复制相似问题