Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

About multiple inheritance and defining virtual function

I have a multiple inheritance scenario without virtual base classes like this:

 Ta  Tb
 |   |
 B   C
  \ /
   A

Ta and Tb are two different template classes that both declare a virtual function named f(). I want to override the two function in the A scope, because I have to interact with both B and C data in these methods. But I don't know how to do this.

class Tb {
protected:
    virtual void f() {};
public:
    void call() {
        this->f();
    };  
};

class Tc {
protected:
    virtual void f() {};
public:
    void call() {
        this->f();
    };
};

class B : public Tb {
public:
    void doSomething() {};
};

class C : public Tc {
private:
    int c;
public:
    void inc() { c++; };
};

class A : public B, public C {
protected:
    void f() { // this is legal but I don't want to override both with the same definition.
        // code here
    }
    // if Tb::f() is called then i want to call C::inc()
    // if Tc::f() is called then i want to call B::doSomething()
public:
    void call() {
        B::call();
        C::call();
    };
};

Is there a syntax to override both the methods with different definitions or do I have to define these in B and C?

Thanks

Edit: My problem is not that a cant call Tb::f() or Tc::f(), but that i want to define two different behavior if Tb::f() or Tc::f() is called. These methods are called by Tb and Tc itself in its own public methods. Modified the example so maybe is more clear what i want to do...

like image 417
Gianni Pisetta Avatar asked May 06 '11 12:05

Gianni Pisetta


1 Answers

Is there a syntax to override both the methods with different definitions or do I have to define these in B and C?

Short answer: no.

Your A:f() will override both Ta::f() and Tb::f().

If you want different overrides, the only solution is to insert helper classes Hb and Hc:

Ta  Tb
|   |
B   C
|   |
Hb  Hc
 \ /
  A 

Hb can be as small as two functions, just to rename the function:

class Hb: public B {
   protected: // overrides from Ta
     virtual void f() { Ta_f(); }

   protected: // new virtuals
     virtual void Ta_f() = 0;
 };

and then you can define A::Ta_f() to do whatever you want (including calling B::f() ! )

like image 78
Sjoerd Avatar answered Oct 21 '22 09:10

Sjoerd