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.
Related
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";}
};
Here's what I mean. I have a class hierarchy:
class A {
virtual int f() = 0;
};
class B : public A {
int f() override {return 5;}
void doSpecificStuff() {}
}
B is a self-sufficient class that can be used on its own. But it also has many descendants:
class C : public B {
int f() override {return 171;}
}
Is there any way to make sure that I won't forget to re-implement f when subclassing B?
This solution is inspired by #dyp's comment:
You could split the two responsibilities of B, namely "provides B-style implementation" and "can be instantiated."
class B_for_implementation : public A
{
void doSpecificStuff();
};
class B_for_objects final : public B_for_implementation
{
int f() override {return 5;}
};
class C final : public B_for_implementation
{
int f() override {return 171;}
};
Self-contained objects would be created from B_for_objects, while other classes would derive from B_for_implementation.
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 {}
};
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;
}
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()
{
}
};