Extending interfaces using inheritance - c++

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()
{
}
};

Related

How to convert a vector of parent pointers to another in c++?

How to convert two parent pointers in c++?
This is the code.
// base class
class B {
public:
virtual ~B() {};
// other code
};
class A {
public:
virtual ~A() {};
// other code
};
// child class
class C1 : public A, B {
public:
virtual ~C1() {};
// other code
};
class C2 : public A, B {
public:
virtual ~C2() {};
// other code
};
// ...other C class
There is a std::vector<std::shared_ptr<A>> which items point to instance C1 or C2 ...Cn.
Does anyone know how to convert the vector to a std::vector<std::shared_ptr<B>>?
Your code has typos. Missing public in inheritance of B when defining C<x> breaks stuff.
After this is fixed sidecast does the job as it should:
dynamic_cast conversion - cppreference.com
b) Otherwise, if expression points/refers to a public base of the most derived object, and, simultaneously, the most derived object has an unambiguous public base class of type Derived, the result of the cast points/refers to that Derived (This is known as a "sidecast".)
// base class
class B {
public:
virtual ~B() { }
};
class A {
public:
virtual ~A() { }
};
class C1 : public A, public B {
public:
virtual ~C1() { }
};
class C2 : public A, public B {
public:
virtual ~C2() { }
};
TEST(SideCast, sigleItemCast)
{
C2 x;
A* a = &x;
auto b = dynamic_cast<B*>(a);
ASSERT_THAT(b, testing::NotNull());
}
TEST(SideCast, sideCastOfVectorContent)
{
std::vector<std::shared_ptr<A>> v { std::make_shared<C1>(), std::make_shared<C2>() };
std::vector<std::shared_ptr<B>> x;
std::transform(v.begin(), v.end(), std::back_inserter(x),
[](auto p) { return std::dynamic_pointer_cast<B>(p); });
ASSERT_THAT(x, testing::Each(testing::NotNull()));
}
Live demo

Implementation of Interface inherited of another Interfaces

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";}
};

get derived classes access the member data and functions of each other

how to make derived classes access the member data and functions of each other. both classes are inherited from base class as pure abstract.
here my scenario
class Base
{
public:
virtual void do_something() = 0;
};
class Derived1 : public Base
{
public:
virtual void do_something()
{
// need to use a2
// need to use func
}
private:
int a1;
};
class Derived2 : public Base
{
public:
virtual void do_something()
{
// need to use a1
}
void func(){}
private:
int a2;
};
Probably you need to re-think your design. There will be no memory allocated to a1 for Derived2's object and similarly for a2 and Derived1. What you are asking is equivalent to saying, both cat and dog are animals, I want to use cat::whiskers in dog.
You probably need this:
class Base
{
public:
virtual void do_something() = 0;
};
class Derived : public Base
{
public:
int a1;
int a2;
void func(){}
};
class Derived1 : public Derived
{
public:
virtual void do_something()
{
// can use a2 and func here
}
};
class Derived2 : public Derived
{
public:
virtual void do_something()
{
// need to use a1
}
void func() override {}
};

How to derive from a pimpl class?

Let's say the scenario is this.
IBase - interface.
BaseImpl - implementation.
BaseStub - allocates std::unique_ptr to BaseImpl named m_impl.
And then how to achieve the following?
IDerived - interface.
DerivedImpl - implementation, inherits from BaseImpl.
DerivedStub - allocates std::unique_ptr to DerivedImpl named m_impl, inherits from BaseStub.
It becomes a problem that BaseStub already allocates its implementation, and since DerivedStub does the same, it conflicts.
class IBase
{
public:
virtual void f1() = 0;
};
class IDerived
{
public:
virtual void f2() = 0;
};
class BaseImpl : public IBase
{
public:
virtual void f1() override {}
};
class DerivedImpl : public BaseImpl, public IDerived
{
public:
virtual void f2() override {}
};
class BaseStub : public IBase
{
public:
BaseStub() { m_impl.reset(new BaseImpl()); }
virtual void f1() override { m_impl->f1(); }
private:
std::unique_ptr<BaseImpl> m_impl;
};
// But this also creates BaseStub::m_impl.
class DerivedStub : public BaseStub, public IDerived
{
public:
DerivedStub() { m_impl.reset(new DerivedImpl()); }
virtual void f2() override { m_impl->f2(); }
private:
std::unique_ptr<DerivedImpl> m_impl;
};

Can a mock class inherit from another mock class in googlemock?

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.