Рефакторинг класса - PullRequest
5 голосов
/ 26 ноября 2010

У меня есть два почти идентичных класса, фактически каждая функция-член идентична, каждый член идентичен, каждая функция-член делает одно и то же. Единственная разница между этими классами заключается в том, как я могу определить переменную их типа:

AllocFactorScientific<102,-2> scientific;
AllocFactorLinear<1.2> linear;  

Вот заголовки для них:

template<double&& Factor>
struct AllocFactorLinear;

template<short Mantissa, short Exponent, short Base = 10>
struct AllocFactorScientific

У меня вопрос: как я могу реорганизовать эти функции из тех классов, которые позволили бы мне иметь только один набор функций, а не два набора идентичных функций.

Ответы [ 4 ]

3 голосов
/ 26 ноября 2010

Извлеките все обычное поведение в третьем классе (для ясности я опускаю аргументы шаблона в своем ответе):

class CommonImpl
{
public:
  void doSomething() {/* ... */ }
};

Затем я вижу два варианта (которые из моеготочка зрения, по крайней мере, в значительной степени эквивалентна):

  • Сделать AllocFactorLinear и AllocFactorScientific наследовать конфиденциально из этого класса и привести нужные вам функции-членыдля предоставления в области действия с помощью директив using:

    class AllocFactorLinear : CommonImpl
    {
    public:
      using CommonImpl::doSomething;
    };
    
  • Объединить класс реализации в AllocFactorLinear и AllocFactorScientific и перенаправить все вызовы в частную реализацию:

    class AllocFactorLinear
    {
    public:
      void doSomething() { impl_.doSomething(); }
    private:
      CommonImpl impl_;
    };
    

Я бы лично выбрал первое решение.

2 голосов
/ 26 ноября 2010

Может быть, попытаться создать некоторый базовый класс с помощью этих функций и сделать это 2 классами с шаблонами для наследования этого базового класса.

0 голосов
/ 26 ноября 2010

Я думаю, это будет что-то вроде:

template <typename Type>
struct AllocFactor {...};

и тогда вы можете иметь Type, например:

template <double&& Factor>
struct LinearConfig
{
    static double value() { return Factor;}
};

и

template <short Mantissa, short Exponent, short Base = 10>
struct FactorScientificConfig
{
    static double value() 
    {
       return some_expression_to_get_factor;
    }
};

Вы можете создать AllocFactor, используя AllocFactor<LinearConfig<1.2>>, и соответствующий с FactorScientificConfig. Затем вы можете использовать статическую функцию-член для возврата значения, рассчитанного для обоих классов, так что AllocFactor<T> может использовать T::value() в качестве значения, сообщаемого классом конфигурации.

0 голосов
/ 26 ноября 2010

Почему вы используете шаблонный класс для этого? Не могли бы вы использовать нетекстовый класс с двумя разными конструкторами?

...