Каскадные вызовы переопределения виртуальных методов - PullRequest
0 голосов
/ 22 мая 2019

Я работаю над большим программным обеспечением, которое сильно зависит от супер-паттерна вызова.

По сути, интерфейс определяет виртуальный метод init(), который затем переопределяется во всех классах, которые его наследуют. Когда init() вызывается для класса, КАЖДЫЕ перегруженные init методы каскадируются, от базового класса до верхнего дочернего класса, и все между ними.

Но пользователь должен сам вызывать метод init() своего прямого родителя, что приводит к следующему коду:

class myClass : public Base
{
    virtual void init()
    {
        Parent::Init() // often forgotten, or misplaced by the developer
        // Do some init stuff
    }
}

Альтернативой этому обычно является использование делегатов. У базового класса есть вещи, которые нужно сделать в init, которые объявлены final в Base, и делегируют часть этого метода onInit(), который наследующие классы должны переопределять. Но это не каскадно обращается ко всем родительским классам, как мне бы хотелось.

Альтернатива, которую я впервые реализовал, - это вариант делегированного подхода. И дочерние классы, и Base реализуют метод onInit() и init(). init() вызывает Parent::init() с последующим вызовом onInit() для себя и генерируется автоматически с использованием шаблонного метапрограммирования и макросов. и onInit() содержит код, специфичный для класса.

# define DELEGATE(T, Parent) \
     void init() override { Parent::init(); T::onInit(); }

struct Base
{
    virtual void init() { Base::onInit(); }
    virtual void onInit() {}
};

struct A : public Base
{
     DELEGATE(A, Base)
     void onInit() override { /* MyCustom code for A */ }
};

struct B : public A
{
     DELEGATE(B, A)
     void onInit() override { /* MyCustom code for B */ }
};

Это работает довольно хорошо ... за исключением того, что множественное наследование становится беспорядком, и даже если обработано, наследование алмаза вызывает проблемы с дублированными вызовами.

Что заставляет меня задуматься: я не могу быть единственным человеком, который ищет шаблон проектирования, решающий мою проблему, и сообщество stackoverflow должно знать об этом:)

Вы когда-нибудь сталкивались с шаблоном дизайна для этого? Я очень жду ваших идей!

1 Ответ

0 голосов
/ 22 мая 2019

Это то, что я хотел бы защитить, чтобы не забыть о переопределении в детских классах.Это простая реализация метода проектирования шаблонного метода:

class Base {
public:
    void init() {
        //base init steps
        childInit();
    }

private:
    virtual void childInit() = 0;
};

class Child : public Base {
private:
    void childInit() override { /*init the child*/}
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...