Avoiding duplication of code - c++

Please refer the following example.
using namespace std;
//Base interface
class IBase
{
public:
virtual void BaseMethod1() = 0;
virtual void BaseMethod2() = 0;
};
class IEntity1 : public IBase
{
public:
virtual void Entity1Method1() = 0;
virtual void Entity1Method2() = 0;
};
class Entity1 : public IEntity1
{
public:
Entity();
//IBaseMethods
void BaseMethod1();
void BaseMethod2();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//EntityMethods
void Method1();
void Method2();
};
In the above example, for all other entities deriving from IBase needs to implement BaseMethod1() and BaseMethod2().Because of which lots of code duplication is happening? Is there anyway where we can avoid redundant implementation of IBase methods in entities deriving from it?

You can use virtual inheritance in combination with a default base implementation class to encapsulate your default base behavior, and have it be only inherited by the concrete classes you want, like follows:
using namespace std;
//Base interface
class IBase
{
public:
virtual void BaseMethod1() = 0;
virtual void BaseMethod2() = 0;
};
class IEntity1 : virtual public IBase
{
public:
virtual void Entity1Method1() = 0;
virtual void Entity1Method2() = 0;
};
class BaseImpl : virtual public IBase
{
public:
virtual void BaseMethod1()
{
...
}
virtual void BaseMethod2()
{
...
}
}
class Entity1 : public IEntity1, public BaseImpl
{
public:
Entity1();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//EntityMethods
void Method1();
void Method2();
};
There is, however, a runtime cost associated with virtual inheritance. Multiple inheritance also comes with some structural issues, e.g. base class construction.
You can even have some fun with template classes to make your class composition more modular:
template<typename TEntity, typename TBaseImpl>
class ConcreteEntity: public TEntity, public TBaseImpl
{
public:
ConcreteEntity() {}
};
class ConreteEntity1 : public ConcreteEntity<IEntity1, BaseImpl>
{
public:
ConreteEntity1();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//ConreteEntity1 Methods
void Method1();
void Method2();
};

You could make a function that is called in BaseMethod1() implementations that are the same.
Something like this:
void BaseMethod1_common();
class Entity1 : public IEntity1
{
public:
Entity();
//IBaseMethods
void BaseMethod1() { BaseMethod1_common(); }
void BaseMethod2();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//EntityMethods
void Method1();
void Method2();
};

First of all IBase deserves a virtual destructor.
Declare it pure virtual and define IBase:BaseMethod1() and
IBase::BaseMethod1().

If your intention is to hide implementation, then the only option would be to release the code as a library and then share only the header file among the other developers.
Implementing a global function, or using multiple inheritance as suggested still mean that your implementation is exposed.
However, if the intent is to reduce coupling among the various classes, there's another option :
Create a class that has the actual shared implementation, and then another class which will be an interface to it.
This interface class will then be the base class for other derived entities.
Example code is shown below :
//First Header and Cpp file
class Base_private
{
public:
BaseImpl(arguments);
~BaseImpl();
void BaseMethod1() {
//Implementation
}
void BaseMethod2() {
//Implementation
}
};
//Second Header and Cpp file
class BaseInterface
{
public:
BaseInterface(arguments);
~BaseInterface();
void BaseMethod1() {
m_pBase->BaseMethod1();
}
void BaseMethod2() {
m_pBase->BaseMethod2();
}
private:
Base_private* m_pBase;
};
class Entity : public BaseInterface
{
public:
Entity(arguments);
~Entity();
void Method1();
void Method2();
};

Related

Remove code duplication for virtual class members in C++ inheritance

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

Inheriting both abstract base interface and its implementation gives C2259

I have the following condition:
An absract base class with many pure virtual functions:
interface IBase
{
virtual void foo1() = 0;
virtual void foo2() = 0;
virtual void foo3() = 0;
virtual void foo4() = 0;
virtual void foo5() = 0;
// ...
virtual void fooN() = 0;
};
Two small interfaces that inherit it:
Version-A:
interface IBaseExt_A :
public IBase
{
virtual void foo_A() = 0;
};
Version-B:
interface IBaseExt_B :
public IBase
{
virtual void foo_B() = 0;
};
I create base class that implements all of the IBase interface functions:
class CBase :
public IBase
{
public:
virtual void foo1() { /* Do something... */}
virtual void foo2() { /* Do something... */}
virtual void foo3() { /* Do something... */}
virtual void foo4() { /* Do something... */}
virtual void foo5() { /* Do something... */}
// ...
virtual void fooN() { /* Do something... */}
};
Now, I want to implement both derived versions with minimal code.
I was hoping to do something like:
class CBaseExt_A :
public IBaseExt_A,
public CBase
{
public:
virtual void foo_A() { /* Do something... */}
};
Apparently this gives error:
C2259: 'CBaseExt_A': cannot instantiate abstract class...These errors refer to all IBase interface functions.
I know I can solve it the long way by delegating all IBase functions to CBase implementation:
class CBaseExt_A :
public IBaseExt_A,
public CBase
{
// IBase implementation:
public:
virtual void foo1() { CBase::foo1();}
virtual void foo2() { CBase::foo2();}
virtual void foo3() { CBase::foo3();}
virtual void foo4() { CBase::foo4();}
virtual void foo5() { CBase::foo5();}
// ...
virtual void fooN() { CBase::fooN();}
// IBaseExt_A implementation:
public:
virtual void foo_A() { /* At last - do what we came here for...*}
};
But this makes my small class CBaseExt_A become big and complex.
Is there a way how to avoid all this manual delegation coding?
Many thanks, PazO
You should use the following code:
interface IBase
{
virtual void foo() = 0;
......
};
class CBase : virtual public IBase
{
void foo() { }
......
};
interface IBaseExt_A : virtual public IBase
{
virtual void foo_A() = 0;
};
struct CBaseExt_A : public IBaseExt_A, public CBase
{
virtual void foo_A() { /* Do something... */ }
};
Note that both places where the IBase class is inherited should be marked as virtual.
I think you should specify one of the two inheritance to be virtual.
That is a diamond inheritance where
IBase is the top level
IBaseExt_A and CBase are the middle level
CBaseExt_A is the bottom level
so in CBaseExt_A you want to specify from which path implement the top level, I would say that you may want to specify CBase inheritance in IBaseExt_A to be public virtual instead of just public.
class CBaseExt_A :
public IBaseExt_A,
public virtual CBase
{
public:
virtual void foo_A() { /* Do something... */}
};

Virtual multiple interface

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.

Extending a nested class method

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

A design qustion about C++ interface(pure virtual class)/multiple inheritance/virtual inheritance

I want to reconstruct my small 3d-engine, it is very small so i place all files in only one project.
now, i want to reconstruct it with interfaces, so i can disperse different modules to the different projects and build them as a dll.
when i do that, i have met a lot of difficulties in the basic design of framework code.
I want to design a 'Object Hierarchy' of my small engine, it is realized in the previous work. for example:
Object
Component
SceneComponent
StaticMeshComponent/SkelMeshComponent
D3DSkelComponent
...
but they are implement directly.
now, i want to use interface(pure virtual class), i have design the basic interfaces(for test ):
#include <cstdio>
#include <iostream>
#include <string>
using namespace std;
class IObject
{
public:
virtual std::string GetName() = 0;
};
class IMesh : public IObject
{
public:
virtual void Draw() = 0;
};
class IStaticMesh : public IMesh
{
public:
virtual void BuildSomeMesh() = 0;
};
class ISkeletalMesh : public IMesh
{
public:
virtual void PlayAnim( const std::string& strAnimName ) = 0;
};
class ID3DSkeletalMesh : public ISkeletalMesh
{
public:
virtual void LoadD3D( const std::string& strD3D ) = 0;
};
it looks like ok, but when i try to implement them, i find that it may be a impossible mission.
first, i can write a template class or normal class for IObject, eg:
template < typename TBase >
class TObject : public TBase
{
public:
virtual std::string GetName()
{
return m_strTest;
}
std::string m_strTest;
};
based on this TObject, I can implement a CMesh:
class CMesh : public TObject< IMesh >
{
public:
virtual void Draw()
{
cout<<"draw mesh" <<endl;
}
};
IMesh* pMesh = new CMesh(); // ok
IObject* pObj = pMesh; // ok
so far, it works well. but how to implement the CStaticMesh/CSkeletalMesh/CD3DSkeletalMesh?
it maybe like this:
class CStaticMesh : public CMesh, public IStaticMesh
{
public:
};
but i have two IObject base class, so i must change all "public xxx" to "virtual public xxx", it looks bad.
another question is CStaticMesh must implement all virtual member function of IStaticMesh, include:
virtual void Draw() = 0;
virtual void BuildSomeMesh() = 0;
even if there is a Draw in CMesh which is a base call of CStaticMesh.
ok, maybe i need a TMesh:
template < typename TBase >
class TMesh : public TObject< TBase >
{
public:
virtual void Draw()
{
cout<<"draw mesh" <<endl;
}
};
and implement CStaticMesh like this:
class CStaticMesh : public TMesh<IStaticMesh>
{
public:
virtual void BuildSomeMesh()
{
cout<<"Build Some Mesh!"<<endl;
}
};
it looks like ok, but how to implment CD3DSkeletalMesh? make a TSkeletalMesh? ok, it is crazy!!!
i think, this is abime.
which is the mistake in this design? how to change the design idea to avoid this dilemma? do you know a idea which can keep the inheritance hierarchy of those interfaces and implement easily?
if i use many virtual inheritance, is there any performance isuue?
You can solve this, as you mentioned, with virtual inheritance. This will create only one instance of a multiply inherited interface class in the hierarchy.
First the interfaces:
class IObject
{
public:
virtual std::string GetName() = 0;
};
class IMesh : virtual public IObject
{
public:
virtual void Draw() = 0;
};
class IStaticMesh : virtual public IMesh
{
public:
virtual void BuildSomeMesh() = 0;
};
class ISkeletalMesh : virtual public IMesh
{
public:
virtual void PlayAnim( const std::string& strAnimName ) = 0;
};
class ID3DSkeletalMesh : virtual public ISkeletalMesh
{
public:
virtual void LoadD3D( const std::string& strD3D ) = 0;
};
Then the implementations:
class CObject : virtual public IObject
{
public:
std::string GetName()
{
return m_strTest;
}
std::string m_strTest;
};
class CMesh : public CObject, virtual public IMesh
{
public:
void Draw()
{
cout<<"draw mesh" <<endl;
}
};
class CStaticMesh : public CMesh, virtual public IStaticMesh
{
public:
void BuildSomeMesh()
{
cout<<"Build Some Mesh!"<<endl;
}
};
...
For the performance implications of this, look at this question.