How does one go about overriding such a function in the example below?
It's clearly not working the way I wrote it, but is it possible to implement something similar?
class Foo
{
public:
class Kid
{
public:
virtual void DoSomething();
};
};
class FirstBar : public Foo
{
public:
void Foo::Kid::DoSomething() override;
};
class SecondBar : public Foo
{
public:
void Foo::Kid::DoSomething() override;
};
My take on it - your bars want to have Kids of their own, properly inheriting:
#include<iostream>
class Foo
{
public:
class Kid
{
public:
virtual void DoSomething() {std::cout<<"Kid!\n";}
};
};
class FirstBar : public Foo
{
public:
class Kid : Foo::Kid {
public:
void DoSomething() override {std::cout<<"Kid Bar 1!\n";}
};
};
class SecondBar : public Foo
{
public:
class Kid : Foo::Kid {
public:
void DoSomething() override {std::cout<<"Kid Bar 2!\n";}
};
};
int main() {
Foo::Kid().DoSomething();
FirstBar::Kid().DoSomething();
SecondBar::Kid().DoSomething();
return 0;
}
Note inheriting from Foo is unnecessary unless Kid is defined as protected, but I left the inheritance in case it makes sense for other reasons.
One way to solve it is to inherit Foo::Kid
Live sample
class FirstBar : public Foo::Kid
You can inherit both Foo and Foo::Kid if you need to:
class FirstBar : public Foo::Kid, public Foo
Related
I'm currently trying to wrap my head around the basics of C++ inheritance. Consider the following piece of code:
// Interfaces
class InterfaceBase
{
public:
virtual void SomeMethod() = 0;
};
class InterfaceInherited : public InterfaceBase
{
};
// Classes
class ClassBase : public InterfaceBase
{
public:
virtual void SomeMethod()
{
}
};
class ClassInherited : public ClassBase, public InterfaceInherited
{
};
int main()
{
ClassBase myBase; // OK
ClassInherited myInherited; // Error on this line
return 0;
}
Here I have two interfaces with an inheritance relationship. The same goes for the two classes which implement the interfaces.
This gives me the following compiler error:
C2259 'ClassInherited': cannot instantiate abstract class
It seems that the class ClassInherited does not inherit the implementation of SomeMethod from ClassBase. Thus it is abstract and cannot be instantiated.
How would I need to modify this simple example in order to let ClassInherited inherit all the implemented methods from ClassBase?
You are encountering a diamond problem.
The solution is to use virtual inheritance (Live), to ensure that only one copy of base class members are inherited by grand-childs:
// Interfaces
class InterfaceBase
{
public:
virtual void SomeMethod() = 0;
};
class InterfaceInherited : virtual public InterfaceBase
{
};
// Classes
class ClassBase : virtual public InterfaceBase
{
public:
virtual void SomeMethod()
{
}
};
class ClassInherited : public ClassBase, public InterfaceInherited
{
};
int main()
{
ClassBase myBase; // OK
ClassInherited myInherited; // OK
return 0;
}
I've got following class Foo and FooBase:
class FooBase
{
public:
virtual void A() = 0;
};
template <class T>
class Foo : public FooBase
{
public:
virtual void A() {}
private:
T mT;
};
FooBase is here to have a instance without needing to know the type, so I can do s.th. like this:
FooBase *foo = new Foo<int>();
Pretty standard. Now the issue: I want to bring the same thing to the next level.
So I've got the class:
template <class T>
class Bar : public Foo<T>
{
public:
virtual void B() {}
};
And can of course use:
Bar<int> *bar = new Bar<int>();
Except I don't know the type of the template class.
So initial idea was to do the following:
class BarBase : public FooBase
{
public:
virtual void B() {}
};
template <class T>
class Bar : public BarBase, Foo<T>
{
};
So I can do the following:
BarBase *bar = new Bar<int>();
For obvious reasons this doesn't work - the question is now: How to get s.th. like this to work?
You can solve this issue with virtual inheritance. This feature assures that there is only one instance of your virtually-inherited base class when you instantiate a subclass. For your example, this would look like:
class FooBase
{
public:
virtual void A() = 0;
};
template <class T>
class Foo : public virtual FooBase
// ^^
{
public:
virtual void A() {}
private:
T mT;
};
class BarBase : public virtual FooBase
// ^^
{
public:
virtual void B() {}
};
template <class T>
class Bar : public BarBase, Foo<T>
{
};
Now you can happily create instances like you wanted:
BarBase *bar = new Bar<int>();
I have encountered a virtual method in a nested class.
##classone.h
class ClassOne: {
public:
class InnerClass{
public:
virtual void method1();
...
##classone.cpp
void ClassOne::InnerClass::method1()
{
...
}
I am subclassing ClassOne and need to extend method1(). What need's to be done with the nested class in that situation?
What I tried
##subclassone.h
class SubClassOne: public ClassOne{
public:
virtual void method1();
##subclassone.cpp
void SubClassOne::InnerClass::method1()
{
##New implementation
}
But that gives a multiple definition of ClassOne::InnerClass::method1()
method1 belongs to ClassOne::InnerClass, not ClassOne. When you inherit from ClassOne, the nested class from base class becomes a member of the derived class, too, and you can reach it by qualifying with either ClassOne:: or SubClassOne::. Hence the double definition error regarding method1.
You'll need to sub-class InnerClass, too. If you still wish to derive from ClassOne, it would look like this:
class ClassOne {
public:
class InnerClass {
public:
virtual void method1();
};
};
void ClassOne::InnerClass::method1()
{
}
class SubClassOne : public ClassOne {
class DerivedInnerClass : InnerClass { //
virtual void method1();
};
};
void SubClassOne::DerivedInnerClass::method1()
{
}
If I have the following code:
class A_Interface {
public:
virtual void i_am_a() = 0;
};
class A : public A_Interface {
public:
void i_am_a() {printf("This is A\n");}
};
class B_interface {
public:
virtual void i_am_b() = 0;
// would like to run i_am_a()
};
class B : public A, public B_interface {
public:
void i_am_b() {printf("This is B\n");}
};
int main() {
B BO;
B_interface* BI = &BO;
BI->i_am_b();
// ******* WOULD LIKE TO RUN THE FOLLOWING ********
BI->i_am_a();
}
What are my options to be able to run the class A member function from B_Interface Pointer?
I know that it is possible for B_interface to inherit A_interface as:
class B_Interface : virtual public A_interface ...
class A : virtural public A_Interface ...
But that makes it impossible using GMOCK to the best of my knowledge to mock class B. What are my options?
Thanks...
Inside class B_interface have:
void i_am_a()
{
// throws if the object does not actually have A as a base
dynamic_cast<A &>(*this).i_am_a();
}
OK, I was wrong, again :(. So here is the answer code can be like this:
class A_Interface {
public:
virtual void i_am_a() = 0;
};
class A : virtual public A_Interface {
public:
void i_am_a() {printf("This is A\n");}
};
class B_Interface : virtual public A_Interface {
public:
virtual void i_am_b() = 0;
// would like to run i_am_a()
};
class B : public A, public B_interface {
public:
void i_am_b() {printf("This is B\n");}
};
GMock can be like this:
class MockB : public B_Interface, public MockA {
MOCK_METHOD0(foo, int(int));
}
This works for me in real application, but seems a little messy.
I have the following class structure:
class InterfaceA
{
virtual void methodA =0;
}
class ClassA : public InterfaceA
{
void methodA();
}
class InterfaceB : public InterfaceA
{
virtual void methodB =0;
}
class ClassAB : public ClassA, public InterfaceB
{
void methodB();
}
Now the following code is not compilable:
int main()
{
InterfaceB* test = new ClassAB();
test->methodA();
}
The compiler says that the method methodA() is virtual and not implemented. I thought that it is implemented in ClassA (which implements the InterfaceA).
Does anyone know where my fault is?
That is because you have two copies of InterfaceA. See this for a bigger explanation: https://isocpp.org/wiki/faq/multiple-inheritance (your situation is similar to 'the dreaded diamond').
You need to add the keyword virtual when you inherit ClassA from InterfaceA. You also need to add virtual when you inherit InterfaceB from InterfaceA.
Virtual inheritance, which Laura suggested, is, of course, the solution of the problem. But it doesn't end up in having only one InterfaceA. It has "side-effects" too, for ex. see https://isocpp.org/wiki/faq/multiple-inheritance#mi-delegate-to-sister. But if get used to it, it may come in handy.
If you don't want side effects, you may use template:
struct InterfaceA
{
virtual void methodA() = 0;
};
template<class IA>
struct ClassA : public IA //IA is expected to extend InterfaceA
{
void methodA() { 5+1;}
};
struct InterfaceB : public InterfaceA
{
virtual void methodB() = 0;
};
struct ClassAB
: public ClassA<InterfaceB>
{
void methodB() {}
};
int main()
{
InterfaceB* test = new ClassAB();
test->methodA();
}
So, we are having exactly one parent class.
But it looks more ugly when there is more than one "shared" class (InterfaceA is "shared", because it is on top of "dreaded diamond", see here https://isocpp.org/wiki/faq/multiple-inheritance as posted by Laura). See example (what will be, if ClassA implements interfaceC too):
struct InterfaceC
{
virtual void methodC() = 0;
};
struct InterfaceD : public InterfaceC
{
virtual void methodD() = 0;
};
template<class IA, class IC>
struct ClassA
: public IA //IA is expected to extend InterfaceA
, public IC //IC is expected to extend InterfaceC
{
void methodA() { 5+1;}
void methodC() { 1+2; }
};
struct InterfaceB : public InterfaceA
{
virtual void methodB() = 0;
};
struct ClassAB
: public ClassA<InterfaceB, InterfaceC> //we had to modify existing ClassAB!
{
void methodB() {}
};
struct ClassBD //new class, which needs ClassA to implement InterfaceD partially
: public ClassA<InterfaceB, InterfaceD>
{
void methodB() {}
void methodD() {}
};
The bad thing, that you needed to modify existing ClassAB. But you can write:
template<class IA, class IC = interfaceC>
struct ClassA
Then ClassAB stays unchanged:
struct ClassAB
: public ClassA<InterfaceB>
And you have default implementation for template parameter IC.
Which way to use is for you to decide. I prefer template, when it is simple to understand. It is quite difficult to get into habit, that B::incrementAndPrint() and C::incrementAndPrint() will print different values (not your example), see this:
class A
{
public:
void incrementAndPrint() { cout<<"A have "<<n<<endl; ++n; }
A() : n(0) {}
private:
int n;
};
class B
: public virtual A
{};
class C
: public virtual A
{};
class D
: public B
: public C
{
public:
void printContents()
{
B::incrementAndPrint();
C::incrementAndPrint();
}
};
int main()
{
D d;
d.printContents();
}
And the output:
A have 0
A have 1
This problem exists because C++ doesn't really have interfaces, only pure virtual classes with multiple inheritance. The compiler doesn't know where to find the implementation of methodA() because it is implemented by a different base class of ClassAB. You can get around this by implementing methodA() in ClassAB() to call the base implementation:
class ClassAB : public ClassA, public InterfaceB
{
void methodA()
{
ClassA::methodA();
}
void methodB();
}
You have a dreaded diamond here.
InterfaceB and ClassA must virtually inherit from InterfaceA
Otherwise you ClassAB has two copies of MethodA one of which is still pure virtual. You should not be able to instantiate this class. And even if you were - compiler would not be able to decide which MethodA to call.