3

Suppose I have the following classes:

class Base {
  virtual void func() { cout << "func base" << endl; }
};

class A : virtual public Base {
  public:
  virtual void func() { cout << "func A" << endl; }
};

class B : virtual public Base {
  public:
  virtual void func() { cout << "func B" << endl; }
};

class C : public A, public B {
  C(bool is_a);
  public:
  virtual void func() { // Call appropriate parent's func here }
};

My requirement is that the appropriate parent class' function func() be called when I call C's func(). This is what I mean by appropriate:

Base* ptr = new C(true /*is_a*/);
ptr->func(); // This should call A's func internally

How to achieve this? Is it even possible?

[edit]

This might be more of a design question. It is known that class C will have only one true parent (either A or B). And depending on which is the parent, I want that function to be called. Any alternative design suggestions are welcome.

I am deriving C from A and B because there is some common functionality which both A and B share and which can't be a part of base class.

nishantsingh
  • 4,537
  • 5
  • 25
  • 51
  • diamond shaped inheritance isn't advised – Tyker Jun 01 '18 at 09:13
  • 1
    Your last edit is weird. You don't need the `static_cast`, just call `ptr->func();` and it will call `C::func()` with polymorphism. – andreee Jun 01 '18 at 09:13
  • 1
    How would the compiler know which is the "correct" function to call? From the point of view of the compiler the "correct" function is `C::func`. If you want to then call a specific parents function you have to do it explicitly. – Some programmer dude Jun 01 '18 at 09:15
  • 1
    Possible duplicate of [How to call a parent class function from derived class function?](https://stackoverflow.com/questions/357307/how-to-call-a-parent-class-function-from-derived-class-function) – Samer Tufail Jun 01 '18 at 09:16
  • I've edited the question to make my intention clear. Please take a look again. @SamerTufail – nishantsingh Jun 01 '18 at 09:17
  • 1
    And your design seems flawed if you need a flag such as "is one type or another". – Some programmer dude Jun 01 '18 at 09:19
  • @Someprogrammerdude Could you suggest a better design? It is known that any instance of class C will have one true parent. – nishantsingh Jun 01 '18 at 09:25
  • @SamerTufail I've modified the question enough for it to be a duplicate of the suggested question. – nishantsingh Jun 01 '18 at 09:35

2 Answers2

6

You need to call A::func() explicitly.

class C : public A, public B {
  public:
  virtual void func() { A::func(); }
};

Update (to yours):

What do you really want to achieve? Is there an actual problem that you want to solve?

If you know that "class C will have only one true parent", why do you need to derive from A and B in the first place? Even though Aconcagua's answer works, it looks more like a workaround for a problem that isn't properly stated from your side. In case you are dealing with different implementations for your class, wouldn't you want to employ some kind of pattern (like the bridge or strategy pattern) instead?

andreee
  • 4,459
  • 22
  • 42
  • I am deriving C from A and B because there is some common functionality which both A and B share and which can't be a part of base class. – nishantsingh Jun 01 '18 at 10:25
3

This might be more of a design question. It is known that class C will have only one true parent (either A or B). And depending on which is the parent, I want that function to be called. Any alternative design suggestions are welcome.

class Base { };
class A : public Base { };
class B : public Base { };
class C
{
    // common interface for all types of C
};

class C_A : public A, public C { };
class C_B : public B, public C { };

Now you can use C_A, wherever a C needs to behave as A and C_B analogously...

In above example, all virtual inheritances are removed, they are not needed as is. Depending on the use case, it might or might not be appropriate to let class C itself inherit from Base. If so, let all of A, B and C inherit virtually from Base. C_A and C_B, though, do not need to inherit virtually from their parents (there still will just be one Base instance inherited due to the virtual inheritance of the base classes).

Aconcagua
  • 24,880
  • 4
  • 34
  • 59
  • 1
    Yes, in design terms that's much better. The OP was all over the place with this. Do we need virtual inheritance at all now? - it comes at a price. – Paul Sanders Jun 01 '18 at 09:57
  • @PaulSanders As far as the concrete example goes, there isn't any need for virtual inheritance any more (hinted to in my last paragraph already). But there might yet be other reasons for we are not aware of... – Aconcagua Jun 01 '18 at 11:02
  • 1
    Could be, but I don't see inheriting from `Base` as being one of them. After all, you already did that when you inherited from `A` or `B`. Good answer though, you helped the OP see the wood for the trees, it got my vote, but maybe take out all the `virtual` s and the final paragraph so we can see _really_ clearly how it should be done. – Paul Sanders Jun 01 '18 at 11:58
  • @PaulSanders Oh, now I see, virtual inheritance from A/B/C as well... Sure, unnecessary, copy/paste error... Last paragraph intended to hint to remove VI from A and B only (as CA/CB shouldn't anyway), now fixed. Thanks for the hint. – Aconcagua Jun 01 '18 at 12:58