Совместно используйте один и тот же вызов функции в двух классах и избегайте пустой реализации, когда это не нужно - PullRequest
0 голосов
/ 25 февраля 2020

Мой вопрос : возможно ли разделить один и тот же вызов функции между двумя унаследованными классами (скажем, Base и Derived) и --- ключевой точкой- - избегать пустых экземпляров в Derived, когда эта функция строго специфицирует c из Base, или и пустых экземпляров в Base, когда эта функция строго Speci c из Derived?

Причина, по которой можно использовать один и тот же вызов, состоит в том, что почти весь код является общим, только некоторые особенности необходимо решать отдельно. Например:

class Base
{
    virtual BaseSpecific();    // Useful in Base
    virtual DerivedSpecific(); // Useless in Base
};

class Derived : Base
{
    BaseSpecific() override;    // Useless in Derived
    DerivedSpecific() override; // Useful in Derived
};

// f() is so similar between Base and Derived that is shared common in Base
Base::f()
{
    ...
    BaseSpecific();
    DerivedSpecific();
    ...
}

Derived::BaseSpecific() {}   // empty implementation in Derived, avoidable?
Base::BaseSpecific() { ... } // define the specific behavior in Base, OK

// or

Derived::DerivedSpecific() { ... } // define the specific behavior in Derived, OK
Base::DerivedSpecific() {}         // empty implementation in Base, avoidable?

Предоставляет ли C ++ решение этой проблемы? Это неизбежно?

Заранее спасибо.

PD: Это похоже на этот поток , но отличается в реализации.

1 Ответ

0 голосов
/ 25 февраля 2020

final ключевое слово запрещает переопределение функции. Так что BaseSpecific подходит для использования. Если мы не хотим, чтобы DerivedSpecific был реализован в Base, мы должны объявить его как pure abstract virtual function.

class Base
{
    virtual void BaseSpecific() final;    // Useful in Base
    virtual void DerivedSpecific() = 0;   // Not possible to implement here with this declaration
};

class Derived : Base
{
    // void BaseSpecific() override; // Error, not possible to override
    void DerivedSpecific() override; // It is possible to override
};

Но если вы так говорите

Потому что код 90% идентичен между Base и Derived, а для оставшихся 10% это сделано специально. Возможно ли улучшение?

Подходящим решением может быть реализация шаблона метода шаблона .

Возможная реализация с помощью примера из ссылки может быть:

#include <iostream>
#include <memory>

class Base
{
    public:

    void templateMethod()
    {
        stepOne();
        stepTwo();
        stepThree();
    }

    protected:

    void stepOne() // And i dont want it to be overriden
    {              // so it is not virtual
        std::cout << "%45 of the code done." << std::endl;

    } 
    virtual void stepTwo() = 0;
    void stepThree() // Again i dont want it to be overridden
    {                // so it is not virtual
        std::cout << "Remaining %45 of the work done." << std::endl;
    }
}; 

class Derived : public Base
{
    protected:
    void stepTwo() override final // I want it to be final
    {
        std::cout << "%10 of the work done." << std::endl;
    }
};

int main()
{
    auto obj = std::make_unique<Derived>();

    obj->templateMethod();
}

Вывод:

% 45 выполненного кода.
% 10 из выполненной работы.
Остальные% 45 выполненной работы.

запуск в режиме онлайн

Можно также выполнить условные действия с помощью шаблон путем изменения описания метода.

Например:

bool stepTwo(); // Declaration
...
...
if ( stepTwo() ) // If second step succeeded
    stepThree(); // Perform step three
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...