two interfaces, multiple inheritance combine into one container? - c++

I stumbled upon the following problem: I have two packages A and B working fine for each own. Each has its own interface and his own implementation. Now i made a package C combining a adapter of A with a concrete Implemenation of B. C actually only implements the Interface of A and is only inheritating and using the Interface of B internally for now. Most of the times that was enough to have only access to the Interface A from a Container, but now i need the methods from B accessible too. Here is the simple example:
//----Package A----
class IA
{virtual void foo() = 0;};
// I cant add simply bar() here, it would make totally no sense here...
class A : public IA
{virtual void foo() {doBasicWork();} };
//----Package B----
class IB
{virtual void bar() = 0;};
class B1 : public IB
{
//Some special implementation
virtual void bar() {}
};
class B2 : public IB
{
//Some special implementation
virtual void bar() {}
};
// + several additional B classes , with each a different implementation of bar()
//---- Mixed Classes
class AB1 : public B1, public A
{
void foo() {A::foo(); B1::bar();}
};
class AB2 : public B2, public A
{
void foo() {A::foo(); B2::bar();}
};
// One Container to rule them all:
std::vector<IA*> aVec;
AB1 obj1;
AB2 obj2;
int main(){
iAvector.push_back(&obj1);
iAvector.push_back(&obj2);
for (std::vector<IA>::iterator it = aVec.begin(); it != aVec.end(); it++)
{
it->for(); // That one is okay, works fine so far, but i want also :
// it->bar(); // This one is not accessible because the interface IA
// doesnt know it.
}
return 0;
}
/* I thought about this solution: to inherit from IAB instead of A for the mixed
classes, but it doesnt compile,
stating "the following virtual functions are pure within AB1: virtual void IB::bar()"
which is inherited through B1 though, and i cant figure out where to add the virtual
inheritence. Example:
class IAB : public A, public IB
{
// virtual void foo () = 0; // I actually dont need them to be declared here again,
// virtual void bar () = 0; // do i?
};
class AB1 : public B1, public IAB
{
void foo() {A::foo(); B1::bar();}
};
*/
The question is, how to achieve a combination of both Packages A and B, so that both Interfaces are accessible from one Container, while all the implementation details from A and B still get inherited?

The obvious solution is to create a combined interface:
class IAB : public virtual IA, public virtual IB
{
};
, have your AB1 and AB2 derive from it (in addition to their
current derivations), and keep IAB* in the vector.
This means that B1 and B2 must also derive virtually from
IB; given the direction things seem to be going, A should
probably also derive virtually from IA.
There are strong arguments that inheritance of an interface
should always be virtual. Without going that far: if a class is
designed to be derived from, and it has bases, those bases
should be virtual (and arguably, if a class is not designed to
be derived from, you shouldn't derive from it). In your case,
you're using the classic mixin technique, and generally, the
simplest solution is for all inheritance in a mixin to be
virtual.

Related

Two folded polymorphism is weird, how to make it extensible?

For example, I have an abstract base class A and B. A has a virtual method as follows
class A
{
public:
virutal void f(B& b) = 0;
};
For class A1
class A1 : public A
{
public:
void f(B& b) override { b.f(A1); }
};
And thus for B, it needs a virtual method f(A1)
class B
{
public:
virtual void f(A1& a) = 0;
};
And in class B1 : public B, the virtual method is implemented. The problem is that when another class A2 : public A is added, I have to add a virtual method virtual void f(A2& a) = 0 in class B, which I think it breaks the code because I don't know if A2 even A1 is added or not when I design class B. How to avoid it but implement the equivalent requirements? Any C++ feature can be used even with templates.
Unfortunately, there's no such thing as a virtual template function in C++ (this is what I believe you're trying to accomplish, after parsing your question).
The closest, and the least ugly solution I can think of, is to have the virtual function in base class B take the base class A as a parameter:
class B
{
public:
virtual void f(A& a) = 0;
};
B1 overrides that, and then uses dynamic_cast to cast its parameter to an instance of A1.
In this manner, you can continue an define each Ax and Bx pair of derived classes, without having to change the API interface in the base class, between the two hierarchies.
A bit ugly, but the question states "any C++ feature can be used", and dynamic_cast certainly qualifies under that requirement.

CPP FakeIt library multiple inheritence

I'm comparing GoogleMock vs FakeIt for writing unit tests. I like FakeIt over GoogleMock because I'm from Java background and FakeIt sticks close to Mockito/JMock syntax which make using the library much easier to write & maintain.
But FakeIt GIT home (https://github.com/eranpeer/FakeIt) says it doesn't support MultipleInheritance and the application im testing has code with multiple inheritance. I dont have to support diamond inheritance, so I would like to know if its just that aspect of multiple inheritance thats not supported or are there other aspects thats not supported as well?
Unfortunately it seems that any type of multiple inheritance is not supported, even if it's just an "interface" that unifies several other "interfaces", e.g.:
struct IA { virtual void a() = 0; };
struct IB { virtual void b() = 0; };
struct IC : public IA, public IB {};
fakeit::Mock<IC> mock; // error :(
(The check is done using std::is_simple_inheritance_layout<T>)
I did, however, find a little workaround for this problem, at least for simple scenarios:
class MockC : public IC {
public:
MockC(IA& a, IB& b) : m_a(a), m_b(b) {}
void a() override { return m_a.a(); };
void b() override { return m_b.b(); };
private:
IA& m_a;
IB& m_b;
};
fakeit::Mock<IA> mockA;
fakeit::Mock<IB> mockB;
MockC mockC(mockA.get(), mockB.get());
// Use mockA and mockB to set up the mock behavior the way you want it.
// Just make sure not to use mockC after they go out of scope!
Here's another workaround that doesn't require you to make a special mock class. All you need to do is to mock each of the base classes, and apply it to an instance of the deriving class by casting the deriving class to a reference of each interface. You do need to apply the mock to an instance of the class. Here is an example:
class I1
{
public:
virtual int one() = 0;
};
class I2
{
public:
virtual int two() = 0;
};
class Both : public I1, public I2
{
public:
virtual int one()
{
return 0;
}
virtual int two()
{
return 0;
}
virtual int three()
{
return one() + two();
}
};
We have pure interfaces I1 and I2 with pure virtual methods one() and two() respectively, all implemented by Both. As you might guess, Both is deliberately designed to produce an incorrect answer to demonstrate the mock. Here is the mock inside a Google Test test:
TEST(both_mock, three)
{
Both both;
Mock<I1> mock1((I1&)both);
Mock<I2> mock2((I2&)both);
When(Method(mock1, one)).Return(1);
When(Method(mock2, two)).Return(2);
ASSERT_EQ(both.three(), 3);
}
And this works and passes. The advantage of this is that you don't need to create a special mock class, and you can use the actual class that inherits multiple classes. The disadvantages are...
The deriving class (both in this case) must be instantiable (e.g., you can't do this with an abstract class or interface that inherits from other abstract classes or interfaces).
If you further subclass the subclass of both interfaces (e.g., class More : public Both), you still need one mock for each interface/base class, and you cannot mock any member declared by Both, More, or any further deriving class.

Proper Inheritance Design

I have three classes named A, B, and C. B inherits from A and C inherits from B. (A -> B -> C).
I also have an abstract base class named IBinary. I'd like to make all of the classes implement the IBinary interface. When I make class A inherit from IBinary, the output of my code is C::readb. When class A does not inherit from IBinary, the output is B:readb.
What is the proper way to make my three classes subscribe to the same interface? If I only have the top class (A) inherit from the interface class, I'll need to refactor my code so that I don't have resolution problems like the one above.
If I explicitly have all of the classes inherit from the interface class then I'll have a more complicated class hierarchy and become closer to having a diamond of death.
#include <iostream>
class IBinary {
public:
virtual void readb( std::istream& in ) = 0;
};
// Basic A -- change whether this inherits from IBinary
class A : public IBinary {
public:
A() {};
void readb( std::istream& in ) {}
};
// Specialized A
class B : public A {
public:
B() {};
void load() {
this->readb(std::cin); // <-- which readb is called?
}
void readb( std::istream& in ) {
std::cout << "B::readb" << std::endl;
}
};
// Specialized B
class C : public B {
public:
C() {};
void readb( std::istream& in ) {
std::cout << "C::readb" << std::endl;
}
void foo() {
B::load();
}
};
int main() {
C c;
c.foo();
}
The virtual in the definition of IBinary::readb makes all the difference.
When you inherit from IBinary, all the readbs in the hierarchy that override the one from IBinary are implicitly virtual, too. So virtual dispacth kicks in, just as it's supposed to.
When you don't, then the call is resolved statically. Because the call is inside B, it is B::readb that gets called.
Just have A inherit from IBinary which will make all the children be usable as the abstract interface IBinary.
The reason you are seeing this behavior is, in short, because A::readb is not declared virtual.
Because IBinary::readb is virtual, when A inherits from it, A::readb becomes virtual by default.
Your code would behave more consistently if you added virtual to every declaration of readb, rather than just the first. For this reason, a lot of code style guides for C++ make it a requirement that all virtual methods be declared virtual in all derived classes, even if they are not the ancestor base class.

Factorizing implementations of pure, virtual functions for a subset of classes

Suppose I have this class hierarchy:
class A {
public:
virtual void foo(Base *b) = 0;
};
class B {
public:
virtual void bar() = 0;
};
class C : public A, public B {
public:
virtual void viz() = 0;
};
class E : public C {
public:
/** Some non-pure virtual functions, does not implement foo */
};
class F : public E {
/** does not implement foo */
}
class G : public E {
/** does not implement foo */
}
Now, I would like to define derived, "templatized" versions of F and G, which declares a method foo(T *s) and where the implementation of foo(Base *s) simply calls foo(T *s) by applying a static_cast.
Moreover, I don't wan to expose the template arguments to A, because users of these interfaces (A, B, C, E) should not be exposed to the template parameters (I'm writing a plugin architecture and user-types that derives a given interface are passed back and forth from plugins to base system).
What I thought was to define this class:
template <typename T>
class GA : public A{
...
}
and to define the "templatized" derivations of F and G like this:
template <typename T>
class GF : public F, public GA {
...
}
the problem is that GF sees two different declarations of foo() (one given by A, the other by GA), so the compiler throws me an error when I try to instantiate GF because foo(Base) is not defined.
How can I solve this?
Why do you need multiple inheritance? Why not just class C : public Impl { ... }?
I think the problem is that Impl inherits class A and class C inherits both Impl and A. This means there will be two instances of class A where first A's foo is implemented by Impl and a seconds one is still pure virtual. Virtual inheritance can solve this problem, for example:
class A {
public:
virtual void foo () = 0;
};
class Impl : virtual public A {
public:
virtual void foo () {}
};
class C
: virtual public A
, public Impl
{
};
I would suggest something different. Declare the function as a pure virtual function, and then just trivially implement it in the derived classes by forwarding the call:
class A {
public:
virtual void foo() = 0;
};
void A::foo() {}
class B : public A {
void foo() { A::foo(); }
};
But that does not mean that you cannot achieve what you are trying to do. If you want to implement that operation in another class and use inheritance, you can do it in two different ways:
Intermediate type:
Implement an intermediate type that provides the functionality, then each derived type can extend either the original A or the intermediate I type:
class I : public A {
public:
void foo() {}
};
class B : public I {}; // inherits the implementation
class C : public A { // needs to provide it's own implementation
void foo() {}
};
Virtual inheritance:
Alternatively you can use virtual inheritance (of the three options I would avoid this). In this way you can create a hierarchy where V inherits virtually from A and provides the implementation. The rest of the classes can either inherit from A directly or inherit from A virtually and also inherit from V. By using virtual inheritance you ensure that there is a single A subobject in your hierarchy:
class V : public virtual A {
public:
void foo() {}
};
class B : public virtual A, V { // Inheritance from V is a detail, can be private
// no need to provide foo
};
Note that this approach is overkill for this particular limited problem, and that it has side effects (the layout of the objects will be different and they will be slightly bigger in size). Again, unless you want to mix and match functions from different sibling classes, I would avoid this.
What was wrong in your code
The problem in your code is that you are inheriting from A multiple times, one through D and another directly. While in the path from D the virtual function is no longer pure, in the direct path from A the virtual function is still undefined.
That also causes the second issue in the error message: ambiguity. Because there are two A subobjects, when you try to call foo on the most derived type, the compiler cannot figure out on which of the two A subobjects you want to execute the request. The same type of ambiguity problems would arise if you tried to cast from the most derived type into A directly, as the compiler would not know to which A you want to refer.
Impl does not implement A's method in D and C, it's a completely different base.
You should derive Impl from A, then derive every class of that subset from Impl instead of A.
If you want to inherit from both the A and Impl, then you need to use virtual inheritance.
Edit:
See #Vlad's answer for more details.

Pimpl idiom with inheritance

I want to use pimpl idiom with inheritance.
Here is the base public class and its implementation class:
class A
{
public:
A(){pAImpl = new AImpl;};
void foo(){pAImpl->foo();};
private:
AImpl* pAImpl;
};
class AImpl
{
public:
void foo(){/*do something*/};
};
And I want to be able to create the derived public class with its implementation class:
class B : public A
{
public:
void bar(){pAImpl->bar();}; // Can't do! pAimpl is A's private.
};
class BImpl : public AImpl
{
public:
void bar(){/*do something else*/};
};
But I can't use pAimpl in B because it is A's private.
So I see some ways to solve it:
Create BImpl* pBImpl member in B, and pass it to A with additional A constructor, A(AImpl*).
Change pAImpl to be protected (or add a Get function), and use it in B.
B shouldn't inherit from A. Create BImpl* pBImpl member in B, and create foo() and bar() in B, that will use pBImpl.
Any other way?
What should I choose?
class A
{
public:
A(bool DoNew = true){
if(DoNew)
pAImpl = new AImpl;
};
void foo(){pAImpl->foo();};
protected:
void SetpAImpl(AImpl* pImpl) {pAImpl = pImpl;};
private:
AImpl* pAImpl;
};
class AImpl
{
public:
void foo(){/*do something*/};
};
class B : public A
{
public:
B() : A(false){
pBImpl = new BImpl;
SetpAImpl(pBImpl);
};
void bar(){pBImpl->bar();};
private:
BImpl* pBImpl;
};
class BImpl : public AImpl
{
public:
void bar(){/*do something else*/};
};
I think the best way from a purely object-oriented-theoretical perspective is to not make BImpl inherit from AImpl (is that what you meant in option 3?). However, having BImpl derive from AImpl (and passing the desired impl to a constructor of A) is OK as well, provided that the pimpl member variable is const. It doesn't really matter whether you use a get functions or directly access the variable from derived classes, unless you want to enforce const-correctness on the derived classes. Letting derived classes change pimpl isn't a good idea - they could wreck all of A's initialisation - and nor is letting the base class change it a good idea. Consider this extension to your example:
class A
{
protected:
struct AImpl {void foo(); /*...*/};
A(AImpl * impl): pimpl(impl) {}
AImpl * GetImpl() { return pimpl; }
const AImpl * GetImpl() const { return pimpl; }
private:
AImpl * pimpl;
public:
void foo() {pImpl->foo();}
friend void swap(A&, A&);
};
void swap(A & a1, A & a2)
{
using std::swap;
swap(a1.pimpl, a2.pimpl);
}
class B: public A
{
protected:
struct BImpl: public AImpl {void bar();};
public:
void bar(){static_cast<BImpl *>(GetImpl())->bar();}
B(): A(new BImpl()) {}
};
class C: public A
{
protected:
struct CImpl: public AImpl {void baz();};
public:
void baz(){static_cast<CImpl *>(GetImpl())->baz();}
C(): A(new CImpl()) {}
};
int main()
{
B b;
C c;
swap(b, c); //calls swap(A&, A&)
//This is now a bad situation - B.pimpl is a CImpl *, and C.pimpl is a BImpl *!
//Consider:
b.bar();
//If BImpl and CImpl weren't derived from AImpl, then this wouldn't happen.
//You could have b's BImpl being out of sync with its AImpl, though.
}
Although you might not have a swap() function, you can easily conceive of similar problems occurring, particularly if A is assignable, whether by accident or intention. It's a somewhat subtle violation of the Liskov substitutability principle. The solutions are to either:
Don't change the pimpl members after construction. Declare them to be AImpl * const pimpl. Then, the derived constructors can pass an appropriate type and the rest of the derived class can downcast confidently. However, then you can't e.g. do non-throwing swaps, assignments, or copy-on-write, because these techniques require that you can change the pimpl member. However however, you're probably not really intending to do these things if you have an inheritance hierarchy.
Have unrelated (and dumb) AImpl and BImpl classes for A and B's private variables, respectively. If B wants to do something to A, then use A's public or protected interface. This also preserves the most common reason to using pimpl: being able to hide the definition of AImpl away in a cpp file that derived classes can't use, so half your program doesn't need to recompile when A's implementation changes.
As stefan.ciobaca said, if you really wanted A to be extendable, you'd want pAImpl to be protected.
However, your definition in B of void bar(){pAImpl->bar();}; seems odd, as bar is a method on BImpl and not AImpl.
There are at least three easy alternatives that would avoid that issue:
Your alternative (3).
A variation on (3) in which BImpl extends AImpl (inheriting the existing implementation of foo rather than defining another), BImpl defines bar, and B uses its private BImpl* pBImpl to access both.
Delegation, in which B holds private pointers to each of AImpl and BImpl and forwards each of foo and bar to the appropriate implementer.
I would do (1) because A's privates are or no business for B.
Actually I would not pass it to A as you suggest, because A makes its own in A::A().
Calling pApimpl->whatever() from Bis also not appropriate (private means private).
The correct way is to do (2).
In general, you should probably consider to make all you member variables protected by default instead of private.
The reason most programmers choose private is that they don't think about others who want to derive from their class and most introductory C++ manuals teach this style, in the sense that all the examples use private.
EDIT
Code duplication and memory allocation are undesired side-effects of using the pimp design pattern and cannot be avoided to my knowledge.
If you need to have Bimpl inherit Aimpl and you want to expose a consistent interface to them through A and B, B would also need to inherit A.
One thing you can do to simplify things in this scenario is to have B inherit from A and only change the contructor such that B::B(...) {} creates a Bimpl, and add dispatches for all methods of Bimpl that are not in Aimpl.