views:

78

answers:

4

Hi,

I'm working on a c++ app and I'm facing a problem: I have a class B derived from the abstract class A that has some event handling methods. A third class C is derived from B and must reimplement some of B methods. Is there a way to implicitly call B's method before calling C's one?

Class diagram:

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

One of the workaround I figured out is to call the parent's method from C using, say, B::foo() inside C::foo(). This works but it is up to the developer to remember to add the call in the method's body.

The other is to define a new virtual method that the child will override and that the parent will call inside its "OnKeyPress" method.

Thank you, 3mpty.

+4  A: 

You have to explicitly call the base class method.

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

Just re-read your question.....

Best thing to do is to implement method in B that lastly calls an additional protected virtual method to be implemented by C.

i.e.

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

And you could make the AdditionalKeyStuff(...) in B pure virtual if you want to force any decendants to override it.

Adrian Regan
that is just what I wrote on the question :(Anyway, thank you
3mpty
In the second form, `B::OnKeyPress()` shouldn't be virtual. (Then this becomes the _Template Method Pattern_, BTW.)
sbi
+1  A: 

No. There's no way to have this implicit call.

Plus you gave the two ways to do this in your question!

Didier Trosset
A: 

That is only possible when the method in question is a constructor, and then only happens when the object is constructed. If you can arrange for all the necessary work to be in a constructor you may have something, but it would be very hard to generalise that solution.

Clifford
I tried that, but I'm developing for the Bada Os and some things cannot be done in the constructor.
3mpty
@3mpty: Bada what? It was not intended as a solution, merely a statement of the only time C++ implicitly calls a base class method, when the subclass method is called.
Clifford
I was just saying that in my specific case it is not possible ;)
3mpty
+1  A: 

"Almost" the same you have in the question, but separating public class interface and inheritance interface - mighty useful for all kinds of instrumentation:

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;
    }
};
Nikolai N Fetissov
This is sometimes called the _Non Virtual Interface Idiom_. `+1` from me.
sbi
Yes, Sutter covers that in one of his *exceptional* books.
Nikolai N Fetissov