代码之家  ›  专栏  ›  技术社区  ›  Cedric H.

从模板化的基类派生的类

  •  0
  • Cedric H.  · 技术社区  · 16 年前

    我对模板的实际使用非常陌生,所以我有以下设计问题。

    我在设计课 Bunch2d 和 Bunch4d 从抽象基类派生的 Bunch :

    class Bunch {virtual void create()=0;};
    class Bunch2d : public Bunch {void create();};
    class Bunch4d : public Bunch {void create();};
    

    班级 束 将包含一个容器,a deque 或A vector (见 this question: Choice of the most performant container (array) 的) Particle S:

    typedef Blitz::TinyVector<double,DIMENSIONS> Particle;
    

    因此,你看到了我的问题: 束 必须包含这个容器,因为我的束上的“基础”操作是“维度无关”(例如“容器大小”、“透明容器”等),所以我认为容器属于基类(“束”有一个“容器”)。

    但是这个容器必须知道派生类的维度(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概念的有效性如何?使用模板化的基类?

    感谢您的帮助/回答/意见。

    3 回复  |  直到 16 年前
        1
  •  2
  •   Matthieu M.    16 年前

    有一个注意事项:不同的模板实例(即参数中具有不同类型的模板类)具有不同的类型,因此不是单个基类。

    如果需要多态性,则需要在设计中添加一个层:

    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 应该禁止属性。

    问题在于耦合,因为 受保护的 向未知数量的类公开属性/方法,这与 public 在这一点上,不可能可靠地说明有多少方法会受到实现更改的影响。

    对于方法来说,这是可以接受的,因为方法可以保持向后兼容(有时会花费一些技巧等)。但仍然)。

    对于属性,这是不可接受的,因为属性是实现细节,而不是接口,并且不能使更改向后兼容。

    所以我劝你不要使用 受保护的 属性。在这种特殊情况下,最好将访问 mParticles 在模板类中,而不公开底层实现。

    小提示:如果你不能在 deque 和 vector 如果不打破持有它们的类之外的东西,那么您就有了一个设计问题。

        2
  •  2
  •   usta    16 年前

    然后,您将失去在运行时将一个bundle类指针指向bunch2d或bunch4d对象的能力,并通过该指针以多态方式操作这些对象。如果不释放它对您很重要,那么不要使基类模板化。否则,这里没有任何虚拟函数和抽象基类的意义,所以我建议您只使用模板。

        3
  •  0
  •   Oliver Charlesworth    16 年前

    首先, Bunch<TwoDimensions> 和 Bunch<FourDimensions> 就继承而言,是完全不相关的类。因此, Bunch2d 和 Bunch4d 没有共同的基类!

    如果这对你来说是个问题的话,你将不得不放弃模板化,并且 DIMENSIONS 在运行时参数化。