2

I am wonder it is available to Declare interface and Implement the interface using multi-inheritance.

For example.

I Declare abstract class for interface.

class Interface{
public:
    virtual int interf1(int a) = 0;
    virtual int interf2(char c) = 0;
};

And than to implement these two interface, i define two classes for each, like below

class Implement1{
public:
    int interf1(int a){
        std::cout << a << a << std::endl;
        return 0;
    }
};

class Inplement2{
public:
    int interf2(char c){
        std::cout << c << c << c << std::endl;
        return 0;
    }
};

And then as Last phase, i define a class which inherit Interface and implement classes all.

class Test : public Interface, public Implement1, public Inplement2{

};

But of course, it is not compiled.

Is there any way to build this kind of functionality?

And Actually i found some way while struggling to make it compiled like below, but i am not sure it is safe way which doesn't make potential error, even though now it seem to work since it is simple code.

class Test : public Interface, private Implement1, private Inplement2{
public:
    virtual int interf1(int a){
        return Implement1::interf1(a);

    };
    virtual int interf2(char c){
        return Inplement2::interf2(c);
    }
};
SangminKim
  • 8,358
  • 14
  • 69
  • 125
  • 1
    Do you understand what private inheritance means in C++... – ravi Nov 24 '14 at 11:55
  • In your first example, `Test` is an abstract class. When you have an abstract base class, you *must* implement the functions in your derived classes. –  Nov 24 '14 at 11:57
  • there was something similar: http://stackoverflow.com/questions/860339/difference-between-private-public-and-protected-inheritance – Neska Nov 24 '14 at 12:00
  • @remyabel Who told you that? You don't have to implement all of them (not even a single one). The result is just another abstract class. When you try to instantiate a class, it can't be abstract, hence *that class* needs to implement all abstract functions. – leemes Nov 24 '14 at 12:25
  • Had closed this with this [Possible Duplicate](http://stackoverflow.com/questions/9251189/multiple-inheritance-with-abstract-and-defined-inherited-functions-of-the-same-n). Reopened for other's reference. A moderator may close it again. – iammilind Nov 24 '14 at 12:44

2 Answers2

3

No, there's no way to override a virtual function declared in a base class except by redeclaring it in a class derived from that base class. You'll need to declare (and define) Test::interf1 and Test::interf2 as you've done in the final example.

This means there's no advantage to such weird tricks with inheritance to provide the implementation. I'd use a more straightforward composition:

class Test : public Interface {
public:
    virtual int interf1(int a){
        return i1.interf1(a);
    }
    virtual int interf2(char c){
        return i2.interf2(c);
    }
private:
    Implement1 i1;
    Inplement2 i2;
};

Another possibility is virtual inheritance:

class Implement1 : public virtual Interface {
    // implement interf1 here
};
class Inplement2 : public virtual Interface {
    // implement interf2 here
};
class Test : public Implement1, public Inplement2 {
};

But I wouldn't recommend this without a good reason. It increases the coupling between the interface and the implementation, and is more likely to melt the brain of someone trying to figure out which functions are declared where.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • Can't you replace those reimplementations with `using` statements when you inherit privately? `using Implement1::interf1;` Then you don't need to repeat the signature (unless I remember the wrong syntax) which is the dangerous part here (what if the parameter type is changed? then your code still compiles because you repeat the keyword `virtual` which is a bad idea IMHO) – leemes Nov 24 '14 at 12:37
  • @leemes: No, a using declaration doesn't declare an override, it just makes the base-class function accessible within the scope of the the derived class. In modern C++, use `override` to avoid the "danger" you describe (although, since the base function is pure virtual, you'll get an error if you fail to override it whether or not you do that). – Mike Seymour Nov 24 '14 at 12:48
2

I suggest two alternatives.

1. Split the interface

Define two interfaces, Interface1 with interf1 method, and Interface2 with interf2 method. Define two implementations Implement1 and Implement2 which inherit from their corresponding (single) interface. Combine those by inheriting from both Implement1 and Implement2.

The problem is that you then can't have a common interface to use as a polymorphic interface type.

2. Use virtual inheritance for the interface

Live demo

Keep your original Interface definition. The implementations both should virtually derive from the interface: class Implement1 : virtual public Interface { ... };. Then, when combining those implementations, don't derive from the interface again but just from your two implementations. Their super-class Interface is going to be merged to a single one (that's what virtual inheritance is for, basically, it's also called Diamond Inheritance).

leemes
  • 44,967
  • 21
  • 135
  • 183