Производный класс от шаблонного базового класса - PullRequest
0 голосов
/ 06 сентября 2010

Я совершенно новичок в реальном использовании шаблонов, поэтому у меня следующий вопрос о дизайне.

Я проектирую классы Bunch2d и Bunch4d, которые происходят от абстрактного базового класса Bunch:

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

Класс Bunch будет содержать контейнер, deque или vector (см. этот вопрос: Выбор наиболее производительного контейнера (массива) ) из Particle:

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

Поэтому вы видите мой вопрос: 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();
};

Можете ли вы дать мне свое мнение об этом дизайне? Будет ли правильным использование шаблонов? Как насчет обоснованности концепций ОО? С шаблонным базовым классом?

Спасибо за помощь / ответ / мнение.

Ответы [ 3 ]

2 голосов
/ 06 сентября 2010

Тогда вы потеряете возможность иметь указатель класса Bunch, указывающий на объекты Bunch2d или Bunch4d во время выполнения, и полиморфно манипулируете этими объектами через этот указатель.Если для вас важно не потерять это, не делайте шаблон базовым.В противном случае нет никакого смысла иметь здесь виртуальные функции и абстрактный базовый класс, так что тогда я бы рекомендовал использовать только шаблон.

2 голосов
/ 06 сентября 2010

Существует одно примечание: разные экземпляры шаблонов (т.е. классы шаблонов с разными типами в параметрах) имеют разные типы и, следовательно, НЕ являются единым базовым классом.

Если вам нужен полиморфизм, вы будетенеобходимо добавить слой в свой дизайн:

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 не нарушая что-либо за пределами класса, который их содержит, у вас возникнет проблема дизайна.

0 голосов
/ 06 сентября 2010

Для начала, Bunch<TwoDimensions> и Bunch<FourDimensions> - совершенно не связанные классы в отношении наследования.Следовательно, Bunch2d и Bunch4d не имеют общего базового класса!

Если это будет проблемой для вас, вам придется покончить с шаблонами, и параметризовать DIMENSIONS ввремя выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...