googlemock: object of mocked class cannot be created - c++

I got a class Car which uses speedInterface (it has a reference on it).
Now I want to mock speedInterface with Mock_SpeedInterface.
class speedInterface
{
public:
virtual ~speedInterface() {}
virtual int GetSpeed(void) = 0;
};
class Mock_SpeedInterface : public speedInterface
{
public:
MOCK_CONST_METHOD0(GetSpeed, int());
};
class Car
{
public:
Car(speedInterface& s) : Speedo(s) {}
virtual ~Car() {}
speedInterface& Speedo;
...
};
TEST(TestCar, Test1) {
Mock_SpeedInterface mockSpeed;
...
}
Trying to create mockSpeed leads to the following compiler error:
Error C2259 'Mock_SpeedInterface': cannot instantiate abstract class
IMHO class Mock_SpeedInterface is not an abstract class because it "implements" GetSpeed.
Why do I get this error and how do I prevent it?

Seems MOCK_CONST_METHOD0(GetSpeed, int()); is wrong. To have an ordinary answer I will quote the comment of the OP:
Changing it to MOCK_METHOD0 fix it.

Related

C++ Solving Diamond Inheritance Without Virtual Inheritance

I have the following diamond class structure that does not compile:
class Base{
int a;
public:
virtual void doSomething();
};
class NotMineToTouch : public Base {};
class MyParentClass : public Base {};
class EvilDiamond : public NotMineToTouch, public MyParentClass {};
// I need these methods (that I cannot necessarily edit) to work for an EvilDiamond
void processBase (Base* b) { b->doSomething; /*...*/} // Cannot edit
void processParent (MyParentClass* p) { p->doSomething; /*...*/} // Can edit
void processNotMine (NotMineToTouch* n) { n->doSomething; /*...*/} // Cannot edit
I know the normal solution is to inherit virtually from Base; however, I am not allowed to change NotMineToTouch (or Base). Is there another solution? I am allowed to change MyParentClass and EvilDiamond at my pleasure; however, EvilDiamond must inherit from MyParentClass and NotMineToTouch, and MyParentClass must inherit from Base and may not inherit from EvilDiamond.
I challenge the following assertion:
EvilDiamond must inherit from MyParentClass and NotMineToTouch
You can probably do something along these lines (depending on your architecture):
class EvilDiamond;
class NotMineToTouchImpl : public NotMineToTouch {
EvilDiamond* tgt_;
public:
NotMineToTouchImpl(EvilDiamond* tgt) : tgt_(tgt) {}
... implement NotMineToTouch here, using tgt_ where you would have used this
};
class MyParentClassImpl : public MyParentClass {
EvilDiamond* tgt_;
public:
MyParentClassImpl(EvilDiamond* tgt) : tgt_(tgt) {}
... implement Base here, using tgt_ where you would have used this
};
class EvilDiamond {
friend class NotMineToTouchImpl;
friend class MyParentClassImpl;
// Creating permanent instances of the API classes
// may or may not be appropriate in your case.
NotMineToTouchImpl nmti_;
MyParentClassImpl pci_;
public:
EvilDiamond () : nmti_(this), pci_(this) {}
NotMineToTouchImpl* getAsNotMineToTOuch() {return &nmti_;}
MyParentClassImpl * getAsParentClass() {return &pci_;}
};
You don't have diamond as you don't use virtual inheritance.
you have some "Y" inheritance currently (EvilDiamond has 2 Base).
Without changing your classes, you may add overloads to instruct compiler what to do:
void processBase (EvilDiamond* evil) {
processBase(static_cast<NotMineToTouch*>(evil)); // Use NotMineToTouch::Base
processBase(static_cast<MyParentClass*>(evil)); // Use MyParentClass::Base
}

inheritance errors- cannot instantiate abstract class\ cannot access protected member declared in class

I am kind of new with this inheritance concept and I cant figure it out what's wrong.
I will be happy for some help please.
so I have three classes and one main:
class BaseClassPipeline
{
protected:
BaseClassPipeline::BaseClassPipeline(void){};
virtual int executeFilter (SRV *p_Srv) = 0;
BaseClassPipeline::~BaseClassPipeline(void){};
};
class filter_A:public BaseClassPipeline
{
**edit: protected and not public**
**public:**
filter_A:::filter_A(void);
int filter_A::executeFilter (SRV *p_Srv){return 1}
filter_A:::~filter_A(void);
};
class PipelineAttr
{
protected:
PipelineAttr::PipelineAttr(FILE *cfgFile, SRV *p_Srv){...};
BaseClassPipeline** PipelineAttr::createPipeline(FILE *cfgFile){...};
int PipelineAttr::getNumOfFilters(){...};
PipelineAttr::~PipelineAttr(void){...};
};
class Pipeline:public BaseClassPipeline, public PipelineAttr
{
public:
Pipeline::Pipeline(FILE *cfgFile, SRV *p_Srv) : PipelineAttr(cfgFile, p_Srv){}
int Pipeline::executePipeline(SRV *p_Srv);
int Pipeline::countFilters();
Pipeline::~Pipeline(void);
};
this is the main:
void main()
{
...
Pipeline pipe(cfgFile, srv); // trying to create instance of pipeline
}
I tried to read some other posts but couldn't figure it out what am I doing wrong.
I get those messages:
'Pipeline' : cannot instantiate abstract class
'filter_A::filter_A' : cannot access protected member declared in class 'filter_A'
thanks.
'Pipeline' : cannot instantiate abstract class
You are inheriting from abstract base class BaseClassPipeline. That means if you don't override pure virtual functions of that class, then your derived class would also be abstract.
class Pipeline:public BaseClassPipeline, public PipelineAttr
{
public:
Pipeline::Pipeline(FILE *cfgFile, SRV *p_Srv) : PipelineAttr(cfgFile, p_Srv){}
int executeFilter (SRV *p_Srv) {} <<<< Now, you have provided the definition.
'filter_A::filter_A' : cannot access protected member declared in class 'filter_A'
Correct syntax for defining filter_A would be:-
class filter_A:public BaseClassPipeline
{
public:
filter_A();
int executeFilter (SRV *p_Srv) { return 1; }
~filter_A();
};

access protected variable - complicated situation with inheritance and sub-classes

Hmm... I'm trying to break down my problem...
There is a library with some classes that do almost what I want. I can't change classes of the library so I want to derive them and change what I need.
In this case there is a derived class in the library with two subclasses. Now I derive the class and the subclasses.
In the second sub-class there is a virtual method witch modifies a protected variable from the first sub-class.
I want to override the virtual method with a new virtual method which calls the old virtual wethod an then modify the protected variable again.
Why am I getting the error in mySubClass2 while accessing fResponse?
How can I solve my problem?
class libraryClass : pulic someLibraryBaseClass {
protected:
libraryClass::librarySubClass2 lookUpFunction(int ID) {
//some magic to find the obj
return obj;
}
public:
class librarySubClass2;
class librarySubClass1 {
public:
librarySubClass1(libraryClass baseObj) {
myBaseObj = baseObj;
}
void someCallingFunction(int ID) {
libraryClass::librarySubClass2 obj = myBaseObj->lookUpFunction(ID)
obj->someHandleFunction(this)
cout << fResponse;
}
protected:
friend class librarySubClass2;
unsigned char fResponse[200];
private:
libraryClass myBaseObj;
};
class librarySubClass2 {
protected:
virtual void someHandleFunction(libraryClass::librarySubClass1* obj) {
snprintf((char*)obj->fResponse, sizeof obj->fResponse, "Some Text...\r\n"
}
};
};
class myDerivedClass : public libraryClass {
public:
class mySubClass2 : public libraryClass::librarySubClass2;
class mySubClass1 : public libraryClass::librarySubClass1 {
protected:
friend class mySubClass2;
};
class mySubClass2 : public libraryClass::librarySubClass2 {
protected:
virtual void someHandleFunction(libraryClass::librarySubClass1* obj) {
libraryClass:librarySubClass2::someHandleFuntion(obj);
snprintf((char*)obj->fResponse, sizeof obj->fResponse, "Add some more Text...\r\n"
}
};
};
Edit: Forgot * in Method of mySubClass2
Possible solution:
class mySubClass2 : public libraryClass::librarySubClass2 {
protected:
virtual void someHandleFunction(libraryClass::librarySubClass1* obj) {
libraryClass:librarySubClass2::someHandleFuntion(obj);
myDerivedClass::mySubClass1* nowMyObj = (myDerivedClass::mySubClass*) obj;
snprintf((char*)nowMyObj->fResponse, sizeof nowMyObj->fResponse, "Add some more Text...\r\n"
}
};
Now I derive the class and the subclasses.
In your example code, you're only deriving the main class and not the subclass. You have to inherit also the subclass:
class libraryClass : pulic someLibraryBaseClass
{
class librarySubClass1 : public someLibraryBaseClass::someLibrarySubClass1 { };
// ....
};
But that can be done only if the subclass is accessible (protected/public).
As far as I can tell you wonder why you can't access obj->fResponse in
void mySubClass2::someHandleFunction(libraryClass::librarySubClass1 obj) { ... }
Well, obj is of type librarySubClass1 which inherits its share of fResponse from the common ancestor. However, that is the share of a relative of mySubClass2, not yours as you are mySubClass2! You can only access the fResponse member of objects which are known to be of type mySubClass which actually happens to be known to be not the case for a librarySubClass1 object.
Getting access to librarySubClass::fResponse is as if you got free access to your uncle's inheritance from your grandparents. Unless you have a very unusual family sharing its wealth freely among all family members, you probably won't have access to your uncle's inheritance either.
Because fResponse in mySubClass2 is treated as protected and at that point it is outside of libraryClass, it only worked on librarySubClass2 because it is inside libraryClass.

Workaround for a Visual studio 2005 c++ inheritance bug

The following code does not compile in Visual Studio 2005:
class OriginalClass
{
public:
class Delegate
{
virtual void original_func()=0;
};
};
class BaseClass
:public OriginalClass::Delegate // Problem line 1
{
public:
class Delegate
{
virtual void base_func(int x) = 0;
};
void original_func()override{} // Problem line 2
};
class DerivedClass : public BaseClass::Delegate
{
public:
virtual void base_func(int x) override {};
};
int main ()
{
DerivedClass derived_object;
derived_object.base_func(10);
}
The build output is:
1>inherit\main.cpp(26) : error C3668: 'DerivedClass::base_func' : method with override specifier 'override' did not override any base class methods
1>inherit\main.cpp(32) : error C2259: 'DerivedClass' : cannot instantiate abstract class
1> due to following members:
1> 'void OriginalClass::Delegate::original_func(void)' : is abstract
1> inherit\main.cpp(7) : see declaration of 'OriginalClass::Delegate::original_func'
If I comment out the lines marked Problem line 1 and Problem line 2 it builds OK. So, the use of override is not a problem, nor is inheriting from the nested class. It seems to have difficulty in figuring out which Delegate class is the correct one to use.
This problem does not exist in VC2008.
Can anyone suggest a workaround for this? Besides the obvious: upgrade to a modern compiler!
Also, I would appreciate it if anyone can point to any documentation of the bug (if it is a bug).
Edit:
#Anonymous Coward suggested using typedefs, it will compile if the OriginalClass is changed to the following:
class OriginalClass
{
public:
class Delegate_t
{
virtual void original_func()=0;
};
typedef Delegate_t Delegate;
};
That seems to be a name resolution problem indeed. It compiles when using typedefs:
class OriginalClass {
// class Delegate { ... };
typedef Delegate delegate_t;
};
class BaseClass : public OriginalClass::delegate_t {
// class Delegate { ... };
typedef Delegate delegate_t;
};
class DerivedClass : public BaseClass::delegate_t {
// ...
};

How to solve a mesh inheritance problem in C++

I have the following set of classes that inherit from each other in a mesh way. In the top level, I have abstract classes. Both Abstract_Class_B and Abstract_Class_C inherit from Abstract_Class_A.
In the second level of inheritance, I have the exact implementations of those classes.
Impl_Class_A inherits from Abstract_Class_A.
Impl_Class_B inherits from both Abstract_Class_B and Impl_Class_A.
Impl_Class_C inherits from both Abstract_Class_C and Impl_Class_A.
When I compile the below code, the compiler compiles perfectly if I do not declare any class in the code. But when I start declaring pointer to the classes in the second level, the compiler gives the following error:
undefined reference to `VTT for ns3::Impl_Class_B'
undefined reference to `vtable for ns3::Impl_Class_B'
I used virtual to tackle the typical diamond problem in inheritance, but I am still not able to compile. It makes sense that the compiler gets confused because of this way of inheritance. But my system requires such a design for those classes. Any solution to fix this problem?
The code:
// Top Level (Level 1)
class Abstract_Class_A
{
};
class Abstract_Class_B: virtual public Abstract_Class_A
{
public:
uint8_t type;
};
class Abstract_Class_C: virtual public Abstract_Class_A
{
};
// Second Level (Level 2)
class Impl_Class_A : virtual public Abstract_Class_A
{
public:
double angle;
};
class Impl_Class_B: virtual public Abstract_Class_B, Impl_Class_A
{
};
class Impl_Class_C: virtual public Abstract_Class_C, Impl_Class_A
{
};
void test()
{
Impl_Class_B* test = new Impl_Class_B ();
}
The problem turned out to be related to other virtual functions inside the original classes that I had in my code. The code above works without any problem. During the development, I had encountered other problems so I post her a new code that solves all these problems with comments mentioned next to them:
// Top Level (Level 1)
class Abstract_Class_A
{
~Abstract_Class_A (); // To solve source type is not polymorphic” when trying to use dynamic_cast
};
class Abstract_Class_B: virtual public Abstract_Class_A
{
public:
uint8_t type;
};
class Abstract_Class_C: virtual public Abstract_Class_A
{
};
// Second Level (Level 2)
class Impl_Class_A : virtual public Abstract_Class_A
{
public:
double angle;
};
class Impl_Class_B: virtual public Abstract_Class_B, virtual public Impl_Class_A // Missing second virtual
{
};
class Impl_Class_C: virtual public Abstract_Class_C, virtual public Impl_Class_A // Missing second virtual
{
};
void test()
{
Impl_Class_B* test = new Impl_Class_B ();
}
Notes:
With this type of inheritance paradigm, you cannot use static_cast but rather dynamic_cast should be used. Check the following discussion.
When using dynamic_cast you should add a virtual destructor to the top class. Check the following discussion about it.