2010-07-27 3 views
1

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

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

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 
    } 
} 

Один из обходного пути я понял, это вызвать метод родительского из С помощью, скажем, B :: Foo() внутри C :: Foo(). Это работает, но разработчик должен помнить, чтобы добавить вызов в тело метода.

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

Спасибо, 3mpty.

ответ

4

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

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

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

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

т.е.

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 чисто виртуальной, если вы хотите, чтобы какие-либо decendants переопределить его.

+0

это именно то, что я писал по этому вопросу: ( Во всяком случае, спасибо – 3mpty

+1

Во второй форме 'B :: OnKeyPress()' не должен быть виртуальным. (Тогда это становится методом шаблона _Template Pattern_, BTW.) – sbi

1

Нет. Нет никакого способа получить этот неявный вызов.

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

0

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

+0

Я пробовал это, но я разрабатываю для Bada Os и некоторые вещи не могут быть сделаны в конструкторе. – 3mpty

+0

@ 3mpty: Bada что? Это не было предназначено как решение, а просто заявление единственный раз, когда C++ неявно вызывает метод базового класса, когда вызывается метод подкласса. – Clifford

+0

Я просто говорил, что в моем конкретном случае это невозможно;) – 3mpty

1

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

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; 
    } 
}; 
+0

Это иногда называют _Non Virtual Interface Idiom_. '+ 1' от меня. – sbi

+0

Да, Саттер покрывает это в одной из своих * исключительных * книг. –

Смежные вопросы