I have an abstract interface IA, which is inherited from interfaces IB and IC with different behaviours. Also I have implementations of this interfaces B from IB and C from IC. What if I need class A implementing IA, but part of implementation it has in B and C. How to provide this.
EDITED:
Minimal, complete example:
#include <iostream>
class IB
{
public:
virtual void function_B() = 0;
};
class IC
{
public:
virtual void function_C() = 0;
};
class IA : public IB, public IC
{
};
class B : public IB
{
public:
virtual void function_B()
{
std::cout << "B\n";
}
};
class C : public IC
{
public:
virtual void function_C()
{
std::cout << "C\n";
}
};
// then I want IA implementation, but also to use
// ready implementation B and C
// this way doesn't work, the class A stays abstract
class A: public IA, public B, public C
{
};
int main()
{
IA *a = new A;
a->function_B();
a->function_C();
}
Your problem is that A inherits two times from IB, once via IA and once via B. The same is true for IC as well.
To solve this diamon problem you have to use virtual inheritance wherever a class inherits directly from IC or IB:
class IA : public virtual IB, public virtual IC
{
};
class B : public virtual IB
{
public:
virtual void function_B()
{
std::cout << "B\n";
}
};
class C : public virtual IC
{
public:
virtual void function_C()
{
std::cout << "C\n";
}
};
You need to re-implement every function of IA in A. But those can be simple forwarders.
I would also recomend aggregation over inheritance, if possible, i.e. not inherit from B and C, but make them members:
class A : public IA {
B b_;
C c_;
public:
void function_B() override { b_.b(); }
void function_C() override { c_.c(); }
};
In your code class A is inherited from class IA , class B and class C and class IA is a abstract class so you can't instantiate it.
And due to Class IA is abstract so youclass A also become abstract.
So you need to override the virtual function of class IA (i-e functions of class IB and class IC) in class A.
So you need to reimplement the above functions in class A
class A : public IA,public B,public C {
public:
void function_B() override { std::cout << "B\n";}
void function_C() override { std::cout << "C\n";}
};
Related
Does it important in which order you inheritence abstact classes, which has same functions ?
class A {
public:
virtual void f1() = 0;
virtual void f2() = 0;
};
class B : public A {
public:
virtual void f1() { globalF1_B(); }
virtual void f2() { globalF2_B(); }
};
class C : public A {
public:
virtual void f1() { globalF1_C(); }
};
class D : public A, public B, public C { };
class E : public A, public C, public B { };
Does D and E classes would be the same, if I would write it like below:
class D{
public:
virtual void f1() { globalF1_C(); }
virtual void f2() { globalF2_B(); }
};
class E {
public:
virtual void f1() { globalF1_B(); }
virtual void f2() { globalF2_B(); }
};
PS. I inheritence class A into class D and class E just in case I can forget make some realization of class A's function.
No there are not the same. Besides an invalid C++ code provided, we can say :
In the first case your classes D and E have two method f1() (one inherited from B and one inherited from C) and one method f2() (inherited from C). If you would be able to construct a D object name d, then d.f1() would be reported as an ambiguity that you would need to clarify either this way : d.B::f1() or this one d.C::f1().
While in the second case your classes will only have two methods f1() and f2().
#include <iostream>
using namespace std;
class A {
public:
virtual void f1() = 0;
virtual void f2() = 0;
};
class B : public A {
public:
virtual void f1() { cout << "B::f1()" << endl; }
virtual void f2() { cout << "B::f2()" << endl; }
};
class C : public A {
public:
virtual void f1() { cout << "C::f1()" << endl; }
virtual void f2() { cout << "C::f2()" << endl; }
};
class D : public B, public C { };
class E : public C, public B { };
int main() {
D d;
// d.f1(); // t.cpp:28:5: error: member 'f1' found in multiple base classes of different types
d.C::f1();
d.B::f1();
}
NO, the first version of D & E won't compile either. there would be ambiguity in resolving f1 and f2 in D and E
There is a compiler issue that I am facing. The code that I want to compile is as follows
#include <iostream>
class IA
{
public:
virtual void f1() = 0;
};
class A
{
public:
virtual void f1() { std::cout << "in A::f1" <<std::endl; }
};
class IB : public IA
{
public:
virtual void f3() = 0;
};
class B : public A, public IB
{
public:
// virtual void f1() { std::cout << "in B::f1" <<std::endl; }
virtual void f3() { std::cout << "in f3" <<std::endl; }
};
int main()
{
IB* b = new B();
b->f1();
b->f3();
std::cout << "Hello, world!\n";
}
Here, If I uncomment B::f1 things workout fine. The current code gives the following compiler error.
source_file.cpp: In function ‘int main()’:
source_file.cpp:32:20: error: cannot allocate an object of abstract type ‘B’
IB* b = new B();
^
source_file.cpp:23:7: note: because the following virtual functions are pure within ‘B’:
class B : public A, public IB
^
source_file.cpp:8:18: note: virtual void IA::f1()
virtual void f1() = 0;
The intent here is that the interface, IA, would be defined in the public headers of the library. The implementation class, A, would be done in the source code. All other classes would make use of this base class(A) to implement the publicly exposed abstract interface. Is this possible?
You should change
class A
to
class A : public IA
But it's not enough, as now you get multiple instances of IA in B. So you have to make the inheritance virtual:
class A : virtual public IA {...};
class IB : virtual public IA {...};
UPDATE But is there a real reason for IB to be inherited from IA? If no, drop it, and you won't need virtual inheritance:
class A : public IA {...};
class IB {...};
int main()
{
IB* b = new B();
// b->f1(); - You can't do it now, but do you really need to?
b->f3();
return 0;
}
How instances of virtual base class are available to derived class,How it can be implemented in following code ?
class A
{
public:
void test();
};
class B : virtual public A
{
};
class c : public A
{
} ;
class D : public B, public C
{
};
See inscribed comments with corrected version:
class A
{
public:
void test();
};
class B: virtual public A // A is a virtual base class
{
};
class C : public A // C is a base class of A
{
} ;
class D: public B, public C // D has two base classes B and C
{
};
By virtue of inheritance, D gets two copies of A, one via B, another via C
You could have only one shared copy of A in D, if you would have declared:
class C : virtual public A // C is a virtual base class of A
{
} ;
class IA
{
public:
virtual void a() = 0;
};
class A: public IA
{
public:
virtual void a()
{
}
};
class IB
{
public:
virtual void b() = 0;
};
class B: public IB, public A
{
public:
virtual void b()
{
}
};
void f(IA* p)
{
}
int main()
{
B b = B();
IB* p = &b;
f(p);
}
Is this the correct way to implement interfaces with inheritance in C++? If so, how do I get the line f(p); in my code to compile? Basically, I would like if IB could inherit from IA but this will cause problems for B.
UPDATE
What I want is for IB to include IA's interface, as follows. However this code wont compile since IA::a() and A::a() conflict with each other. What should I do?
class IA
{
public:
virtual void a() = 0;
};
class A: public IA
{
public:
virtual void a()
{
}
};
class IB : public IA
{
public:
virtual void b() = 0;
};
class B: public IB, public A
{
public:
virtual void b()
{
}
};
UPDATE 2
This compiles, does it look correct? Do I need all these virtuals
class IA
{
public:
virtual void a() = 0;
};
class A: virtual public IA
{
public:
virtual void a()
{
}
};
class IB: virtual public IA
{
public:
virtual void b() = 0;
};
class B: virtual public IB, public A
{
public:
virtual void b()
{
}
};
Well, this is the right way of course, but the line f(p) should not compile as is, imagine classes that implement IB, but don't implement IA, it's possible, so you cannot assume that they all implement IA. If you want to assume that, you can inherit IB from IA, but this is another design. It can be implemented like this:
class IA
{
public:
virtual void a() = 0;
};
class A: virtual public IA
{
public:
virtual void a()
{
}
};
class IB : virtual public IA
{
public:
virtual void b() = 0;
};
class B: public IB, public A
{
public:
virtual void b()
{
}
};
Can a mock class inherit from another mock class in googlemock? If yes, then please help me in understanding why isn't this working.
class IA
{
public:
virtual int test1(int a) = 0;
};
class IB : public IA
{
public:
virtual float test2(float b) = 0;
};
class MockA : public IA
{
public:
MOCK_METHOD1(test1, int (int a));
};
class MockB : public MockA, public IB
{
public:
MOCK_METHOD1(test2, float (float b));
};
I get a cannot instantiate abstract class compiler error for MockB but not for MockA
If you plan on using multiple inheritance, you should be using virtual inheritance.
Next example compiles and link fine :
class IA
{
public:
virtual int test1(int a) = 0;
};
class IB : virtual public IA
{
public:
virtual float test2(float b) = 0;
};
class MockA :virtual public IA
{
public:
int test1(int a)
{
return a+1;
}
};
class MockB : public MockA, public IB
{
public:
float test2(float b)
{
return b+0.1;
}
};
int main()
{
MockB b;
(void)b;
}
It is just a small modification of your example
Class MockB inherits from IB which has two purely abstract functions: test1 and test2. And you need to override both of them. Inheriting from MockA which overrides test1 is insufficient (at lest in C++ - in Java it would work). So the fix is to add
virtual int test1(int a)
{
return MockA::test1(a);
}
to MockB definition.