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;
}
Related
I tried to compile the program, but compiler treats ParameterExpr class as abstract. I did not work with multiple inheritance and I thought that it should be work (because get_type was actually implemented in Expr class)
class IMetaExpression
{
public:
virtual int get_type(void) = 0;
virtual ~IMetaExpression(){}
};
class IParameterExpression : public IMetaExpression
{
public:
virtual char get_parameter(void) = 0;
};
class Expr : public IMetaExpression
{
public:
virtual int get_type(void) override { return 0; }
};
class ParameterExpr : public Expr, public IParameterExpression
{
public:
virtual char get_parameter(void) override { return 'c';}
//virtual int get_type(void) override { return 0; }
};
int main()
{
auto p = new ParameterExpr();
p->get_type();
delete p;
return 0;
}
I believe this is an issue called the diamond problem.
https://www.geeksforgeeks.org/multiple-inheritance-in-c/
This is where two classes inherit fully or partially from a base class, which then also has a child class inheriting both of these classes. Creating a diamond shape.
The solution to this is adding virtual to the inheritance of the two middle classes. Resulting in:
class IParameterExpression : virtual public IMetaExpression
and
class Expr : virtual public IMetaExpression
This allows the constructor of the base class to be called only once and sharing functionality between all inherited classes.
I am not an expert on the diamond problem, so more clarification is appreciated.
I have got myself into a strange issue now. Ill write a really simplified version of the same.
class Base
{
public:
virtual int func1()=0;
virtual int func2()=0;
protected:
int n;
};
class der1: public Base
{
// implements the virtual functions of the base and uses the protected data
// members of the base.
};
class der2: public Base
{
// implements the virtual functions of the base and uses the protected data
// members of the base.
}
Now the problem.... both der1 and der2 implements the virtual functions of base pretty much the same way. But some other classes (der3, der4) has their own implementations. But still need to inherit from base.
How do i refactor the code to remove the code duplication in an oop manner?
Here's one solution using an intermediate layer of another abstract base class:
class Base12 : public Base {
protected:
int commonFuncStuffA() {
// Commonly used stuff
}
int commonFuncStuffB() {
}
};
class der1: public Base12
{
public:
virtual int func1() {
n = commonFuncStuffA();
}
virtual int func2() {
n = somethingElse;
}
};
class der2: public Base12
{
public:
virtual int func1() {
n = commonFuncStuffA();
}
virtual int func2() {
n = commonFuncStuffB();
}
};
What I'd do for real production code design looks a bit different though.
Declare an interface for the pure virtual functions
struct IMyInterface {
virtual int func1() = 0;
virtual int func2() = 0;
virtual ~IMyInterface {}
};
Provide a abstract base class with the commonly used data members and functions
class BaseImpl : public IMyInterface {
protected:
int n;
int commonFuncStuffA() {
// Commonly used stuff
}
int commonFuncStuffB() {
// Commonly used stuff
}
};
Provide implementations of the interface in the finally derived classes
class der1: public BaseImpl {
public:
virtual int func1() {
n = commonFuncStuffA();
}
virtual int func2() {
n = somethingElse;
}
};
class der2: public BaseImpl {
public:
virtual int func1() {
n = commonFuncStuffA();
}
virtual int func2() {
n = commonFuncStuffB();
}
};
class der3: public IMyInterface {
public:
virtual int func1() {
// Some completely different implementation of the interface
}
virtual int func2() {
// Some completely different implementation of the interface
}
};
class der4: public IMyInterface {
public:
virtual int func1() {
// Some completely different implementation of the interface
}
virtual int func2() {
// Some completely different implementation of the interface
}
};
Option 1
You may consider using your most common implementation in the Base class. The main feature or drawback of this method is that the base class would no longer be abstract. If this is a problem, go to option 2.
Maybe you can even cope with differences in the derived classes by using the template method pattern to extract the differences in protected virtual functions invoked by the template method.
In anyway, for derived classes that need a completely different appoach, you'd just override the the Base class' method.
class Base
{
public:
virtual int func1();
virtual int func2()=0;
protected:
virtual void f1_specific_part1()=0;
virtual void f1_specific_part2()=0;
int n;
};
int Base::func1() { // common skeleton of the algorithm
...
f1_specific_part1();
...
f1_specific_part2();
...
}
class Der1: public Base
{
protected:
void f1_specific_part1() override; // Implements the specific variation
virtual void f1_specific_part2() override;
};
Option 2
You may consider to factorize the common code of the derived classes into a protected method of the Base class.
The override of the pure virtual function would then just call the base class protected common function (for der1 and der2) or just use their own implementation that is completely different (for der3 and der4).
class Base
{
public:
virtual int func1()=0;
virtual int func2()=0;
protected:
int common_part1_funct1(); // implements some common parts
int common_part2_funct1();
int n;
};
class Der1: public Base
{
...
int func1() override {
common_part1_funct1();
...
common_part2_funct1();
...
}
};
Option 3 ?
Important remark: My answer assumes that there are many commonalities between most of the derived classes. However if you have only a small subset of derived classes that share some commonalities, then the answer of Evg would be would be more appropriate.
The idea with Base12 is:
struct Base {
virtual int func1() = 0;
virtual int func2() = 0;
};
struct Base12 : Base {
protected:
int func12();
};
struct Der1: public Base12 {
virtual int func1() {
return func12();
virtual int func2() {
return func12();
};
struct Der2: public Base12 {
virtual int func1() {
return func12();
virtual int func2() {
return func12();
};
Let a class hierarchy :
class Base { virtual ~Base() throw(); };
class DerivedA : public Base { };
class DerivedB : public Base { };
I would like to have some code specific to each of these derived classes. However that code also being specific to the application that makes use of this class hierarchy, I do not want to embbed this derived-class-specific code into these derived classes. To avoid doing so, I thought about writing free functions :
void DerivedASpecificWork( DerivedA da );
void DerivedBSpecificWork( DerivedB db );
However, when given an instance of a derived class through a reference/pointer to a Base, I do not have access to the actual type of the instance, and thus cannot call the proper Derived*SpecificWork() function.
I would like to know if there is nome kind of design pattern that would allow me to call a derived-class-specific function without knowing the actual type of the instance, i.e having the same mechanism as virtual functions provide, but without having these virtual functions that would require me to embbed application-specific code into that class hierarchy.
Actually, why I want to do that is to provide informations about an exception that occured within a natively implemented function called by a Lua script. Each exception carrying its own set of information, the way I want to represent the error within the script depends on the type of the exception. I could create a pure virtual method in the base class that would be implemented by derived classes, but this would require me to embbed Lua-related code into my exception hierarchy, which I do not want to do since the Lua is specific to one of the application using that exception hierarchy.
Also I cannot use C++11.
Thank you.
May be Brigde pattern can help you.
This pattern can be used when you want to avoid a permanent binding between an abstraction and it's implementation.
(I don't see your comment about your restriction in using c++11, but you can remove std::unique_ptr, std::move and override keyword)
class AppSpecificImp
{
public:
virtual void DoWork() = 0;
};
class Base
{
public:
virtual ~Base() throw();
virtual DoWork() = 0;
};
class DerivedA : public Base
{
public:
DerivedA(std::unique_ptr<AppSpecificImp> appImp)
: imp(std::move(appImp))
{
}
void DoWork() override
{
// DerivedA specific code
imp->DoWork();
}
private:
std::unique_ptr<AppSpecificImp> imp;
};
class DerivedB : public Base
{
public:
DerivedB(std::unique_ptr<AppSpecificImp> appImp)
: imp(std::move(appImp))
{
}
void DoWork() override
{
// DerivedB specific code
imp->DoWork();
}
private:
std::unique_ptr<AppSpecificImp> imp;
};
Edit to show Visitor pattern usage:
With visitor pattern you can do what you want but with more Effort.
class Visitor
{
public:
virtual void VisitDerivedA(DerivedA* object) = 0;
virtual void VisitDerivedB(DerivedB* object) = 0;
};
class Base
{
public:
virtual void Visit(Visitor* visitor) = 0;
};
class DerivedA : public Base
{
public:
virtual void Visit(Visitor* visitor)
{
visitor->VisitDerivedA(this);
}
};
class DerivedB : public Base
{
public:
virtual void Visit(Visitor* visitor)
{
visitor->VisitDerivedB(this);
}
};
class AppSpecificVisitor : public Visitor
{
public:
void VisitDerivedA(DerivedA* object)
{
// Do any work related to DerivedA class
}
void VisitDerivedB(DerivedB* object)
{
// Do any work related to DerivedB class
}
}
int main()
{
AppSpecificVisitor myVisitor;
Base* myBase = // any class in your hierarchy
myBase->Visit(&myVisitor);
}
As I said in comments with Visitor pattern you can add new functionally without changing the main hierarchy(Base->Derived types). You just define a new visitor implementation and write your logic for every class in main hierarchy. In your example you can pack app specific logic in an object and reference that in your derived objects that is an easier approach.
Why not using a new set of hierarchy for application specific implementation ?
class AppBase
{
public:
virtual ~AppBase() throw();
virtual void work_with_app() = 0;
};
class Base
{
public:
Base(AppBase& app) : m_app(app) {}
virtual ~Base() throw();
protected:
AppBase& m_app;
};
class DerivedA : public Base { DerivedA(AppBase& app) : Base(app) {} };
class DerivedB : public Base { DerivedA(AppBase& app) : Base(app) {} };
// Application specific implementation :
class AppLuaSpecific : public AppBase
{
public:
void work_with_app() { /* Lua app specific */ }
};
This way, your 1st hierarchy : Base, DerivedA, DerivedB can live without knowing anything about the app specific code implemented in AppLuaSpecific.
You can implement your own app-specific dispatch as follows (check it live on Coliru):
#include <iostream>
#include <typeinfo>
struct Base { virtual ~Base() {} };
struct DerivedA : public Base { };
struct DerivedB : public Base { };
namespace AppSpecific
{
template<class F>
void dispatch(const Base& b)
{
const std::type_info& t = typeid(b);
if ( t == typeid(DerivedA) )
F::doit(static_cast<const DerivedA&>(b));
else if ( t == typeid(DerivedB) )
F::doit(static_cast<const DerivedB&>(b));
}
struct Foo
{
static void doit(const DerivedA& da) { std::cout << "Foo(DerivedA)\n"; }
static void doit(const DerivedB& db) { std::cout << "Foo(DerivedB)\n"; }
};
struct Bar
{
static void doit(const DerivedA& da) { std::cout << "Bar(DerivedA)\n"; }
static void doit(const DerivedB& db) { std::cout << "Bar(DerivedB)\n"; }
};
} // namespace AppSpecific
int main()
{
DerivedA da;
DerivedB db;
Base& b1 = da;
Base& b2 = db;
AppSpecific::dispatch<AppSpecific::Foo>(b1);
AppSpecific::dispatch<AppSpecific::Foo>(b2);
AppSpecific::dispatch<AppSpecific::Bar>(b1);
AppSpecific::dispatch<AppSpecific::Bar>(b2);
}
I need help for an implementation that uses multiple inheritance of Interfaces...
There is an existing code whith an interface which has a lot of functions. The instances are created using a factory.
class IBig
{
// Lot of pure virtual functions
};
And his inplementation:
class CBig: public IBig
{
// Implementation
}
I Want to split the interface in multiple smaller interfaces, but it should stay compatible to the existing code for some time.
Here is a sample of what I tried to do:
class IBaseA
{
public:
virtual void DoA() = 0;
};
class IBaseB
{
public:
virtual void DoB() = 0;
};
// The same interface, now based on multiple smaller interfaces
class IBig : public IBaseA, public IBaseB
{
};
class CBaseA: public IBaseA
{
public:
virtual void DoA()
{
printf("DoA\n");
}
};
class CBaseB: public IBaseB
{
public:
virtual void DoB()
{
printf("DoB\n");
}
};
// Inherit from base classes where the implementation is, and from IBig as
// the instance of CBig is returned as IBig.
class CBig: public CBaseA, public CBaseB, public IBig
{
};
The problem here is that the class CBig cannot be instanciated. The compiler says the functions DoA and DoB are pure virtual, even if they are inplemented in CBaseA and CBaseB. What should I do if i don't want to implement again the functions, just to call the function of the base class ?
NB: I know the design is ugly, but this is only temporary until the big interface can be replaced, and.... I want to understand ! ;-)
Thanks in advance !
Here we should use 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:
#include <cstdio>
class IBaseA
{
public:
virtual void DoA() = 0;
};
class IBaseB
{
public:
virtual void DoB() = 0;
};
// The same interface, now based on multiple smaller interfaces
class IBig : virtual public IBaseA, virtual public IBaseB
// ^ ^
{
};
class CBaseA: virtual public IBaseA
// ^
{
public:
virtual void DoA()
{
printf("DoA\n");
}
};
class CBaseB: virtual public IBaseB
// ^
{
public:
virtual void DoB()
{
printf("DoB\n");
}
};
// Inherit from base classes where the implementation is, and from IBig as
// the instance of CBig is returned as IBig.
class CBig: public CBaseA, public CBaseB, public IBig
{
};
int main()
{
CBig cb;
}
The above changes ensure that there are not extra declarations of DoA and DoB created when you inherit from IBaseA and IBaseB multiple times.
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.