Marco Freudenberger
Marco Freudenberger

Reputation: 689

C++ multiple inheritance / virtual inheritance

For a project, I want to hide some implementation details from the library interface. The only way I came up to handle this "efficient" (in terms of coding and maintenance) was with multiple inheritance of abstract and concrete base classes based on the same abstract base. So, yes, I ended up with an extended diamond structure.

I'm usually trying to avoid multiple inheritance whenever possible due to it's complications, so I'm not very experienced in using it and so I'm unsure if the design I'm comming up with has some pitfalls I don't oversee.

Basically I need to provide multiple "tools". Those "tools" have of course some implementation details I want to hide using interface ABCs, for example:

class Tool1Impl : public ITool1;

class Tool2Impl : public ITool2;

However, of course the tools have quite some commonalities.

So I would like to have a common base class, but implementation details again should be hidden through interfaces.

I came up with the following (diamond) scheme :

            ITool                                           
          /   |   \               
        /     |     \
      /       |       \
ITool1  ToolImplBase   ITool2  ... IToolN
  \       /      \      /
   \     /        \    /
    \   /          \  /
   ToolImpl1      ToolImpl2    ... IToolImplN

ToolImplBase implements pure virtual functionality of ITool. ToolImpl1 implements pure virtual functionality declared in ITool1.

Implementation outline looks like:

class ITool {
public:
  virtual int common_foo(int a) = 0;
};

class ITool1 : public virtual ITool {
public:
  virtual int specific_foo(int b) = 0;
};

class ITool2 : public virtual ITool {
public:
  virtual int specific_bar(int c) = 0;
};

class ToolImplBase : public virtual ITool {
public:
  virtual int common_foo(int a) override;
protected:
  int _some_common_data;
};

class ToolImpl1 : public ToolImplBase, public virtual ITool1 {
public:
  virtual int specific_foo(int b) override;
private:
  int _some_specific_data;
};

class ToolImpl2 : public ToolImplBase, public virtual ITool2 {
public:
  virtual int specific_bar(int c) override;
private:
  int _some_specific_data;
};

It seems to do what I want, but I'm not sure if there any potential pitfalls or obvious issues with this. I'm also not sure if I got the "virtuals" in the inheritance scheme all right (not the virtual methods, but the ": public virtual "). One issue is, that MSVC (I'm stuck with 2010 due to some external depencies at this time) gives me a compiler warning C4250:

warning C4250: 'ToolImpl1': inherits'ToolImplBase::ToolImplBase::common_foo' via dominance

Can I just ignore that? I'm not even sure why I'm getting this, because the non-dominant way to "common_foo" is pure virtual, so there actually is no valid "non-dominant" implementation.

Thanks for any input (except for "never use M.I.", I'm trying to avoid it where possible already).

Upvotes: 3

Views: 610

Answers (1)

cokceken
cokceken

Reputation: 2076

There is some explanation about the warning in here: What does C4250 VC++ warning mean?

I think there is no problem with your code because you designed ITool1 as an interface.

If you implement the common_foo function in ITool1, you wouldn't know which implementation of the common_foo will work when you create a ToolImpl1.

You will be careful about the issue but anyone else can legally implement common_foo function in IToolX implementation without an error raising.

My final comment is: why do you need your ITool1 to be derived from ITool? ToolImpl1 is already derived from ToolImplBase so your actual implementation class will always be derived from ITool.

I would change IToolX interface as below

class IToolX{
    public:
    virtual int specific_foo(int b) = 0;
};

Upvotes: 0

Related Questions