перегрузка конструкторов классами друзей - PullRequest
3 голосов
/ 12 апреля 2011

У меня есть класс, который использует статический список (firstFriend в примере) или динамический список (secondFriend в примере) для инициализации. Функциональность списка, которую я не хотел писать для примера, потому что это не важно. Ключевая проблема заключается в том, что firstFriend и secondFriend, ну, в общем, друзья. Код конструкторов класса "target" такой же: если я перегружаю конструкторы, я дублирую точно такой же код. Я не могу шаблонизировать конструкторы, потому что это не работает.

Вот пример (ПРИМЕЧАНИЕ: firstFriend и secondFriend могут выглядеть одинаково, но они НЕ одинаковы в АКТУАЛЬНОМ коде, это просто сильно уменьшенная модель, различия между их атрибутами и функциональностью не имеют никакого различия конструктор класса «target», потому что части открытого интерфейса используются из обоих классов, которые абсолютно одинаковы):

template <class T>
class firstFriend 
{
    public:
    firstFriend() {};

    firstFriend(const T& t) {};

    private:
    T tAttribute; 
};


template <class T>
class secondFriend 
{
    public:

    secondFriend() {};

    secondFriend(T t) : tAttribute(t) {};

    friend class firstFriend<T>;

    private:

        T tAttribute;
};

class target
{
    public:
    target(const firstFriend<int>&) 
    {
        // Some nice initialization of the TargetData.
    }
    target(const secondFriend<int>&)
    {
        // Exactly the same initialization as above. 
        // To the single character. 
    }; 
    private:
    firstFriend<int> TargetData;
};

Вопрос: как перегрузить конструкторы без написания (копирования / вставки) одного и того же кода дважды? Я пытался шаблонизировать конструкторы, но это не сработало. Может быть, неявное приведение? Что было бы наиболее эффективным способом (firstFriend и secondFriend - ОГРОМНЫЕ списки данных). Заранее спасибо!

1 Ответ

1 голос
/ 12 апреля 2011

Если оба конструктора имеют одинаковый код, вы можете написать шаблон конструктора как:

template<class FriendType >
target(const FriendType &) 
{
    // Some nice initialization of the TargetData.
}

Если есть небольшая разница, но большая часть кода одинакова, то вы можете написать шаблонную функцию init и вызвать ее из обоих конструкторов следующим образом:

  target(const firstFriend<int>& arg) 
  {
     init(arg);
     //other code
  }
  target(const secondFriend<int>& arg)
  {
     init(arg);
     //other code
  }
private:
  template<class FriendType >
  void init(const FriendType &) 
  {
     //common code
  }
...