0

I'm trying to derive a class from two abstract base classes.

#include <stdio.h>

class A
{
public:
    virtual void Method(void) = 0;
};

class B
{
public:
    virtual void Method(void) = 0;
};

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

void C::A::Method(void)
{
    printf("C::A::Method\r\n");
}

void C::B::Method(void)
{
    printf("C::B::Method\r\n");
}

C test;

If I try to compile, I get the following error by the linker:

undefined reference to `vtable for C'

If I change the declaration of class C to

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

The compiler gives the following errors:

cannot declare member function 'A::Method' within 'C'

cannot declare member function 'B::Method' within 'C'

What I want to achieve is to make C providing an implementation for both abstract interfaces A and B. Does anybody know how to do it right? Thanks.

TLI123
  • 31
  • 2
  • 1
    Did you try also defining `C::Method()`? – Code-Apprentice Jun 15 '18 at 14:22
  • 1
    What is the purpose of defining `Method()` in both `A` and `B`? Are these classes used elsewhere? – Paul Sanders Jun 15 '18 at 14:58
  • Class A and B are intended to be used as abstract interfaces that are to be consumed elsewhere in the design. The purpose of C is to be the producer of interfaces A and B simultaneously. If I have e.g. a method requiring a a pointer to an instance of A, C shall be compatible to it. The same applies for interface B. Actually, when I add C::Method, as suggested, the code compiles. But if I try to execute test.Method(), ((A*) &test)->Method() and ((B*) &test)->Method(), all calls seem to end up calling test.Method(). – TLI123 Jun 15 '18 at 15:53
  • @TLI123 Of course, that's how virtual methods work . I think you need to [read a good book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – Paul Sanders Jun 17 '18 at 04:33
  • @Paul Sanders: Thanks for the book recommendation. But are you sure you really got my point? My problem is that both Method()'s from class A and B seem to be merged together in class C somehow. What I would expect is that the compiler keeps track of from which class each method is inherited and that both A::Method() and B::Method() are available in class C. So why am I allowed to implement C::A::Method and C::B::Method if there is no way to ever call them? I'm not allowed to declare A::Method() and B::Method() in class C. That appears inconsistent to me. – TLI123 Jun 18 '18 at 08:08
  • Added an alternate solution to the linked question: [link]https://stackoverflow.com/questions/18398409/c-inherit-from-multiple-base-classes-with-the-same-virtual-function-name/50911548#50911548 – TLI123 Jun 18 '18 at 14:23
  • @TLI123 I notice that you didn't answer my question. Why declare `Method()` in both class `A` and class `B`. Do you have some concrete reason for doing so? Name clashes like this are best avoided for what I hope are obvious reasons. – Paul Sanders Jun 19 '18 at 07:24
  • @Paul Sanders Think of class A and class B as abstract interfaces each designed for a special purpose. Example: Class A implements an spi interface and contains a method called WriteData. Class B implements a i2c interface that also contains WriteData. The derived class now should become a controller for a chip containing both interfaces. A consumer requiring an spi interface should be able to operate on the spi part of the controller, while a consumer requiring the i2c should be able to operate on the i2c part. – TLI123 Jun 19 '18 at 14:36
  • @TLI123 Why are these interfaces abstract? Why not implement `WriteData` for your `spi` class in your `spi` class and `WriteData` for your `i2c` class in your `i2c` class? That's where you're going wrong. – Paul Sanders Jun 19 '18 at 15:54
  • @Paul Sanders: These interfaces are abstract because I want to decouple the spi respectively i2c consumer's code from the spi and i2c implementation specifics. Furthermore, it may happen, that I have an additional spi or i2c controller for a different hardware, so I have additional classes that are derived from the same interfaces but come with an entirely different implementation. This shall be transparent to the consumer so it is available to operate either on the one or on the other spi/i2c controller implementation through a unique interface. – TLI123 Jun 20 '18 at 12:00
  • OK, makes sense. In that case, the solution you posted to the linked thread seems fine to me, I will sign off now. – Paul Sanders Jun 20 '18 at 15:49

0 Answers0