Принудительное выполнение родительского метода перед дочерним методом без явного вызова - PullRequest
1 голос
/ 27 июля 2010

Я работаю над приложением c ++ и столкнулся с проблемой: У меня есть класс B, полученный из абстрактного класса A, который имеет несколько методов обработки событий. Третий класс C является производным от B и должен переопределять некоторые из методов B. Есть ли способ неявно вызвать метод B перед вызовом метода C?

Диаграмма классов:

class A
{
    virtual void OnKeyPress(event e)=0;
};
class B : public A
{
    virtual void OnKeyPress(event e)
    {
    print("Keypressed: "+e)
    };
};
class C : public B
{
    void OnKeyPress(event e)
    {
    //DoSomething
    }
}

Один из обходных путей, который я нашел, - это вызов метода родителя из C с использованием, скажем, B :: foo () внутри C :: foo (). Это работает, но разработчик должен не забыть добавить вызов в тело метода.

Другой способ - определить новый виртуальный метод, который дочерний элемент будет переопределять и который родительский объект будет вызывать внутри своего метода OnKeyPress.

Спасибо, 3mpty.

Ответы [ 4 ]

4 голосов
/ 27 июля 2010

Вы должны явно вызвать метод базового класса.

class C : public B
{
    virtual void OnKeyPress(event e)
    {
        B::OnKeyPress(e);
        // Do stuff
    }
};

Просто перечитайте ваш вопрос .....

Лучше всего реализовать метод в B, которыйнаконец, вызывает дополнительный защищенный виртуальный метод, который будет реализован C.

т.е.

class B : public A
{
  protected:
       virtual void AdditionalKeyStuff(event e) { }

  public:

    virtual void OnKeyPress(event e)
    {
        // Do B Stuff

        // Finally give decendants a go.
        AdditionalKeyStuff(e)
    }
};


class C : public B
{
  protected:

    virtual void AdditionalKeyStuff(event e)
    {
        // Do only C stuff
    }
};

И вы можете сделать AdditionalKeyStuff (...) в B чисто виртуальным, если вы хотите принудительно вызвать любойпотомки переопределить его.

1 голос
/ 27 июля 2010

«Почти» то же самое, что и у вас в вопросе, но разделение интерфейса открытого класса и интерфейса наследования - очень полезно для всех видов контрольно-измерительных приборов:

class A
{
private:

    virtual void DoOnKeyPress( event ) = 0;

    void PreKeyPress( event ) { /* do something */ }
    void PostKeyPress( event ) { /* do something */ }

public:

    virtual ~A() {}

    void OnKeyPress( event e )
    {
        PreKeyPress( e );
        DoOnKeyPress( e );
        PostKeyPress( e );
    }
};

class B : public A
{
private:

    virtual void DoOnKeyPress( event e )
    {
        std::cout << "Keypressed: " << e << std::endl;
    }
};
1 голос
/ 27 июля 2010

Нет. Нет такого неявного вызова.

Плюс вы дали два способа сделать это в своем вопросе!

0 голосов
/ 27 июля 2010

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

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