Шаблонный шаблон: изменение архитектуры алгоритма - PullRequest
0 голосов
/ 01 октября 2018

Я использую шаблон шаблона метода в моем проекте, как показано ниже

class Template
{
public:
void algorithm();
{
    A();
    B();
}
private:
virtual void A()=0;
virtual void B()=0;
}

У меня есть несколько подклассов, реализующих метод A & B по-разному.Но теперь мне нужен новый класс Template2 для реализации немного другого алгоритма.

class Template2
{
public:
void algorithm();
{
    A();
    B();
    C();
}
private:
virtual void A()=0;
virtual void B()=0;
void C()
{
    //some stuff
    A();
    //some stuff
    B();
}
}

C идентичен для всех подклассов, поэтому я не делаю его виртуальным,Прямо сейчас я создаю новую иерархию наследования на основе Template2 , но это кажется глупым, потому что мне приходится копировать и вставлять код каждого подкласса в эту новую иерархию.Есть ли способ сделать это более элегантно?

РЕДАКТИРОВАТЬ Извините, я не прояснил свою точку зрения.Теперь у меня есть две иерархии наследования.1. Абстрактный класс Template и некоторые подклассы A1,A2,A3,A4...2. Абстрактный класс Template2 и некоторые подклассы B1,B2,B3,B4...Это прекрасно работает, но мне интересно, есть ли способ каким-то образом объединить эти две иерархии, потому что A1 и B1 имеют одинаковый код, за исключением того, что они получены из Template и Template2 соответственно.Для меня не имеет значения, является ли метод шаблона шаблономОтветы bcperth и Spotted у меня работают :)Большое спасибо.

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Я согласен с Spotted, но рассматривали ли вы просто добавление дополнительных алгоритмов в свой класс template?Это все еще шаблон шаблона с несколькими алгоритмами.Вы получаете более толстый класс, но нет повторения кода.Ниже приведена иллюстрация.

#include <iostream>

using namespace std;

class Template
{
public:
    void algorithm1()
    {
        A();
        B();
    }

    void algorithm2()
    {
        A();
        B();
        C();
    }

private: void C()
    {
    cout << endl << "start C() ";
    A();
    cout << "middle C() ";
    B();
    cout << "end C()" << endl;
    }

private:
    virtual void A() = 0;
    virtual void B() = 0;
};

class real :public Template {

    void A() { cout << "A(1)  "; }
    void B() { cout << "B(1) "; }
};

int main()
{
    real Real;
    cout << "algorithm1" <<endl;
    Real.algorithm1();
    cout << endl;
    cout << endl << "algorithm2 << endl";
    Real.algorithm2();

    return 0;
}
0 голосов
/ 01 октября 2018

Во-первых, простите мой плохой синтаксис C ++.

Я предлагаю вам отделить A() и B() от Template, чтобы вам было проще использовать их в Template2

class Strategy
{
    public:
    virtual void A()=0;
    virtual void B()=0;
}

Тогда есть общий предок между Template и Template2:

class AbstractTemplate
{
    public:
    virtual void algorithm()=0;
}

И, наконец, реализация Template и Template2 в качестве "конечных" классов (= нет необходимости в подклассах).

class Template : AbstractTemplate
{
    public:
    Template(Strategy strategy)
    {
        this.strategy = strategy;
    }
    void algorithm()
    {
        strategy.A();
        strategy.B();
    }
    private:
    Strategy strategy;
}

class Template2 : AbstractTemplate
{
    public:
    Template2(Strategy strategy)
    {
        this.strategy = strategy;
    }
    void algorithm()
    {
        strategy.A();
        strategy.B();
        C();
    }
    private:
    Strategy strategy;
    void C()
    {
        //some stuff
        strategy.A();
        //some stuff
        strategy.B();
    }
}

Перекрытие между Template и Template2 минимально (учитывая, что вам не нужны подклассы, я думаю, что это нормально).

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