Abstract Factory in C++ - c++

I'm trying to understand the abstract factory pattern, here is my first approximation:
#include <iostream>
using namespace std;
class Soldier
{
public:
virtual void shoot()=0;
};
class Archer: public Soldier
{
public:
void shoot(){
cout<<"Archer shoot"<<endl;
}
};
class Rider: public Soldier
{
public:
void shoot(){
cout<<"Rider shoot"<<endl;
}
};
class AbstractFactory
{
public:
virtual Soldier* createArcher()=0;
virtual Soldier* createRider()=0;
};
class OrcFactory: public AbstractFactory
{
Soldier* createArcher()
{
return new Archer();
};
Soldier* createRider()
{
return new Rider();
};
};
class HumanFactory: public AbstractFactory
{
Soldier* createArcher()
{
return new Archer();
};
Soldier* createRider()
{
return new Rider();
};
};
class Game
{
public:
AbstractFactory* factory;
Game(AbstractFactory* factory):factory(factory){};
};
int main()
{
Game* game = new Game(new HumanFactory);
Archer* HumanArcher = static_cast <Archer*>(game->factory->createArcher());
Rider* humanRider = static_cast <Rider*>(game->factory->createRider());
HumanArcher->shoot();
humanRider->shoot();
return 0;
}
This is what I want to reproduce:
I have experience in programing but I'm newbie with patterns, not sure if this is the optimal solution or even if it's a good solution.
I'm reading about game engine architecture, but I'm stuck in this, not by errors, just doubt about the right solution for this exercise. The book has basic examples but not enough to understand it at all.

That's not exactly what makes an abstract factory. In your case, you would need a structure like this (the diagram ended up a bit too big, click the image to see it at its original resolution):
The idea is that you have a family of abstract classes or interfaces (here the units, archer, rider, etc.) and a family of concrete implementations for each type of factory (implementations for humans, implementations for orcs, etc.). The game uses only the abstract factory interface and does not need to care which are the actual types, while each implementation only needs to provide its own behaviour, allowing for easy extension.
As a side note, I used covariant return types in the diagram because C++ supports it (as opposed to, for example, C#) and it seems to make sense in this case (e.g. the method makeArcher in the base factory interface SoldierFactory is declared to return an Archer object, but the same method in OrcSoldierFactory returns a OrcArcher), but that is not strictly required by the pattern.

Related

Functionality of a pure virtual function with variable return type - workaround/design?

I'm working on a very, very simple data access layer (DAL) featuring two classes: DataTransferObject (DTO) and DataAccessObject (DAO). Both classes are abstract base classes and need to be inherited and modified for a specific use case.
class DataTransferObject {
protected:
//protected constructor to prevent initialization
};
class DataAccessObject {
public:
virtual bool save(DataTransferObject o) = 0;
virtual DataTransferObject* load(int id) = 0;
};
in case of a House class from the business logic layer, the implementation of the DAL classes would read something along these lines:
class Dto_House : public DataTransferObject {
public:
int stories;
string address; //...which are all members of the House class...
Dto_House(House h);
};
class Dao_House : public DataAccessObject {
public:
bool save(Dto_House h) { /*...implement database access, etc...*/ }
Dto_House* load(int id) {/*...implement database access, etc...*/ }
};
EDIT: Of course, the derived classes know about the structure of the House class and the data storage.
Simple, nice, okidoke.
Now I wanted to provide a method toObject() in the DTO class in order to quickly convert the Dto_House into a House object. I then read about the automatic return type deduction in C++14 and tried:
class DataTransferObject {
public:
virtual auto toObject() = 0;
};
But I had to discover: No automatic return type deduction for virtual functions. :(
What are your ideas about implementing a "virtual function with deduced return type" for this specific case? I want a general toObject() function in my DTO "interface".
The only thing that came to my mind was something like:
template <typename T>
class DataTransferObject {
virtual T toObject() = 0;
};
class Dto_House : public DataTransferObject<House> {
public:
int stories;
string address;
House toObject() {return House(stories, address);}
};
EDIT:
A possible use case would be:
House h(3, "231 This Street");
h.doHouseStuff();
//save it
Dto_House dtoSave(h);
Dao_House dao;
dao.save(dtoSave); //even shorter: dao.save(Dto_House(h));
//now load some other house
Dto_House dtoLoad = dao.load(id 2);
h = dtoLoad.toObject();
h.doOtherHouseStuff();
But the house does not know it can be saved and loaded.
Of course, the abstract DAO class may be derived to further refine it for the use with, e.g. Sqlite, XML files or whatever... I just presented the very basic concept.
How about setting an empty abstract class - practically, an interface, then have both of your types implement it and set this as the toObject returning reference type?
class Transferable
{
virtual ~Transferable() = 0;
}
And then:
class DataTransferObject {
public:
//Return a reference of the object.
virtual Transferable& toObject() = 0;
};
Dto_House : public DataTransferObject, Transferable { /*...*/ }
House : public DataTransferObject, Transferable { /*...*/ }
The example above is to get my point.
Even better, you can use the DataTransferObject for this cause as your returning reference type, and no other abstract class:
class DataTransferObject {
public:
virtual DataTransferObject& toObject() = 0;
};
Dto_House : public DataTransferObject { /*...*/ }
House : public DataTransferObject { /*...*/ }
Update: If you want to have the classes separated apart, separating any association between data and operations by convention, you could set the name of the base class on something that represents the data i.e.: Building, Construction etc, and then use it for the reference type in toObject.
You can also have the class manipulating those operations on the API of data manipulation.
In general, you can not have a virtual function returning different types in different subclasses, as this violates the whole concept of statically typed language: if you call DataTransferObject::toObject(), the compiler does not know what type it is going to return until runtime.
And this highlight the main problem of your design: why do you need a base class at all? How are you going to use it? Calling DataTransferObject::toObject(), even if you use some magic to get it work (or use a dynamically typed language), sounds like a bad idea since you can not be sure what the return type is. You will anyway need some casts, or some ifs, etc, to get it working — or you will be using only the functionality common for all such objects (House, Road, etc.) — but then you just need a common base class for all of them.
In fact, there is one exception to the same return type rule: if you return a pointer to a class, you can use the Covariant return type concept: a subclass may override a virtual function to return a subclass of the original return type. If all your "objects" have a common base class, you may use something along the lines of
struct DataTransferObject {
virtual BaseObject* toObject() = 0;
};
struct Dto_House : public DataTransferObject {
virtual House* toObject() { /*...*/ } // assumes that House subclasses BaseObject
};
However, this will still leave the same problem: if all you have in your code is DataTransferObject, even if you (but not the compiler) know it is a Dto_House, you will need some cast, which might be unreliable.
On the other hand, you template solution seems quite good except that you will not be able to explicitly call DataTransferObject::toObject() (unless you know the type of the object), but that's a bad idea as I have explained.
So, I suggest you think on how you are going to actually use the base classes (even write some sample code), and make your choice based on that.

Factory pattern with private constructors in C++

I am trying to implement a factory pattern that consists of
a factory class
an abstract class with protected constructor
inherited classes with private constructors and virtual public
destructors.
I want to make sure that
No other one than the factory can not create any instance
If a new inherited class is defined it will not require any modification on interface class and already defined inherited classes. Juts new class implementation and adding into factory classes create method.
I also do not want to write same-like code(like static factory method per inited) for every inherited class and leave the future developers much work for factory connections.
i.e with pseduo code
class Factory;
class Interface
{
protected:
Interface(){/*Do something*/};
public:
virtual ~Interface(){/*Do something*/}
/*I wish I could do below and it is valid for all inherited
classes but friendship is not inherited in C++*/
//friend Interface* Factory::create(Type)
};
class InheritedA:public Interface
{
private:
InheritedA(){/*Do something*/};
public:
virtual ~InheritedA(){/*Do something*/}
/*I dont want to do below two lines for every inherited class*/
//friend Interface Factory::create(Type)
//public: Interface* factoryInheritedA(){return new InheritedA();}
};
class InheritedB:public Interface
{
private:
InheritedB(){/*Do something*/};
public:
virtual ~InheritedA(){/*Do something*/}
};
class Factory
{
static Interface* create(Interface type)
{
switch(type)
{
case A:
return new InheritedA();
case B:
return new InheritedB();
default:
//exceptions etc
}
}
}
int main()
{
Interface* I = Factory::create(A/*or B*/);
return 0;
}
Above code is the cloest I put out. Any suggestions (a speciality of C++, a different design,...) is welcome.
I don't think this a good idea, but here is a way to do this. You create a Tag type which can only be created by the Factory and make all the constructors take a parameter of that type.
class Factory;
class Tag
{
Tag() {}
friend Factory;
};
class Interface
{
public:
Interface(Tag t) {}
virtual ~Interface() {}
};
struct Impl1: public Interface
{
Impl1(Tag t): Interface(t) {}
};
class Factory
{
public:
Interface* makeInstance()
{
return new Impl1( Tag{} );
}
};
void foo()
{
Impl1 i( Tag{} );
}
You will get a compiler error in foo() because Tag::Tag is private.
You could have a templated function:
template<typename Type>
std::unique_ptr<Interface> make_interface() {
// exceptions etc..
}
template<>
std::unique_ptr<Interface> make_interface<InheritedA>() {
return std::make_unique<InheritedA>();
}
template<>
std::unique_ptr<Interface> make_interface<InheritedB>() {
return std::make_unique<InheritedB>();
}
but I really don't see the point in all of this Javaesque boilerplate. Not to mention that you are transforming a compile time information (the type) into a runtime one (via exceptions) for no reason really.
I would just go with:
std::unique_ptr<Interface> ptr_a = std::make_unique<InheritedA>();
std::unique_ptr<Interface> ptr_b = std::make_unique<InheritedB>();
when needed.
It is rarely a good practice to use Factory. I count it as an anti-pattern together with the Singleton. In good design, classess do not concern themselves on how they are created. In your case, when used in Factory, how do you create your class using custom allocator? On stack? In shared memory? In memory-mapped file? From the buffer? In place? This is all really hard to cover in Factory, but do not despair - the simple and elegant solution is ditch the factory!

Access to 'inner' classes in case of composition

I have certain functionality encapsulated in classes which I use in another class. I think this is called composition.
class DoesSomething01
{
public:
DoesSomething01();
void functionality01();
void functionality02();
};
class DoesSomething02
{
public:
DoesSomething02();
void functionality01();
void functionality02();
};
class ClassA
{
public:
ClassA();
private:
DoesSomething01 *m_doesSomething01;
DoesSomething02 *m_doesSomething02;
};
If I have now a ClassB which "knows" ClassA and have to use/execute functionality01 and/or functionality02 of classes DoesSomething01 and/or DoesSomething02 I see two possibilities:
a) Add methods like this to ClassA to provide ClassB direct access to DoesSomething01 and/or DoesSomething02:
DoesSomething01 *getDoesSomething01() { return *m_doesSomething01; }
DoesSomething02 *getDoesSomething02() { return *m_doesSomething02; }
ClassB could then do something like this:
m_classA->getDoesSomething01()->functionality01();
b) Add (in this case four) methods to ClassA which forwards the method calls to DoesSomething01 and DoesSomething02 like this:
void doesSomething01Functionality01() { m_doesSomething01->functionality01(); }
void doesSomething01Functionality02() { m_doesSomething01->functionality02(); }
void doesSomething02Functionality01() { m_doesSomething02->functionality01(); }
void doesSomething02Functionality02() { m_doesSomething02->functionality02(); }
Which option is better and why?
What are the advantages/disadvantages of each option?
First option can be considered a code smell. According to Robert C. Martin's 'Clean Code' it is "Transitive Navigation" and should be avoided. Quoting the author:
In general we don’t want a single module to know much about its
collaborators. More specifically, if A collaborates with B, and B
collaborates with C, we don’t want modules that use A to know about C.
(For example, we don’t want a.getB().getC().doSomething();.)
Second option looks better. It is classical use of Facade pattern. And it is better, because it hides other functionalities of classes DoesSomthing01 and DoesSomthing02. Then you ve'got simplified view of it which is easier to use than 1st option.
Edit: there is also one more thing. You've got two classes which have the same functionalites and are aggregated by other class. You should consider using Stratey pattern here. The your code will look like this:
class DoesSomething
{
public:
virtual void functionality01() = 0;
virtual void functionality02() = 0;
}
class DoesSomething01 : DoesSomething
{
public:
DoesSomething01();
void functionality01();
void functionality02();
};
class DoesSomething02 : DoesSomething
{
public:
DoesSomething02();
void functionality01();
void functionality02();
};
class ClassA
{
public:
ClassA();
DoesSomething* doesSomething(); // Getter
void doesSomething(DoesSomething* newDoesSomething); // Setter
// ...
private:
DoesSomething *m_doesSomething;
};
Then you will need only two method instead of four:
void doesFunctionality01() { m_doesSomething->functionality01(); }
void doesFunctionality02() { m_doesSomething->functionality02(); }
The first scenario is a violation of law of Demeter, which says that a class can only talk to its immediate friends. Basically the problem with the first approach is that any change in the inner classes DoSomething01 and DoSomething02 will trigger a change in Class A as well as Class B because both classes are now directly dependent on these inner classes.
The second option is better as it encapsulates the class B from inner classes but a side effect of this solution is that now class A has a lot of methods that does nothing fancy except for delegating to its inner classes. This is fine but imagine if DoSomething01 has an inner class DoSomething03 and class B needs to access its functionality without directly knowing about it than the class A would need to have another method that would delegate to DoSomething01 that would in turn delegate to DoSomething03. In this case I think it is better to let class B directly know about DoSomething01 otherwise class A is going to have a huge interface that simply delegates to its inner classes.
If there are many classes and/or many methods to be called it makes sense to invent
an interface in the form of an abstract parent class:
class SomeInterface
{
public:
SomeInterface(){}
virtual void functionally01() = 0;
virtual void functionally02() = 0;
}
DoesSomthing01 and other classes would then inherit this class:
class DoesSomthing01 : public SomeInterface
and implement the methods.
If it make sense to associate a key with the instantiation of such a class
you could store these objects in ClassA e.g. using a map (here I
use an integer as the key):
class ClassA
{
private:
std::map<int, SomeInterface*> m_Interfaces;
public:
SomeInterface* getInterface(const int key)
{
std::map<int, SomeInterface*>::iterator it(m_Interfaces.find(key));
if (it != m_Interfaces.end())
return it->second;
else
return NULL;
}
};
From ClassB you could then access them
int somekey = ...;
SomeInterface *myInter = m_classA->getInterface(somekey);
if (myInter)
myInter->functionally01();
This way you have just one access method (getInterface()) independent
of the number of objects.
In order to encode the access to the methods using a key you could
create a map which maps a key onto a closure or a simple switch statement:
in SomeInterface:
public:
void executeMethod(const int key)
{
switch(key)
{
case 1: functionally01(); break;
case 2: functionally01(); break;
default:
// error
}
int methodKey = ...;
int objectKey = ...;
SomeInterface *myInter = m_classA->getInterface(objectKey);
if (myInter)
myInter->executeMethod(methodKey);
Looks like a good case for a Mediator Pattern.
This pattern manage communication between 2 objects that he owns.

Using C++ templates to create a class with custom components

Let me explain what I am asking for by an example. Imagine I have a class for a car.
Now, the car may have a lot of extras:
4 doors instead of only 2
Automatic door locking
4 Wheel drive
I want to create the class with any combination of these options. Any of these options needs some data members. Imagine the class now looks like this:
class Car {
public:
bool FourDoors;
bool AutomaticDoorLocking;
bool FourWheelDrive;
Door doors[4]; //4 only needed if FourDoors=true
DoorLockingElectronic doorElectronic; //Only needed if AutomaticDoorLocking=true
TransmissionsShafts[4]; //4 only needed for FourWheelDrive=true
void lockDoors() {
if (AutomaticDoorLocking) {
doorElectronic.lockDoors();
} else {
// Do manual door locking
}
}
};
So far so good, but now I want to create a lot of cars, so many that memory gets critical. And I do not need most of the extras in most of those cars.
I could create a base class, and derive classes with those options enabled or disabled.
But I would have to create 2^{#extras} classes to create all possible combinations, with a lot of double code.
So I thought maybe templates could be used? (that is the question).
I can imagine having a flag template, and rewrite the lockDoors like this:
template<int flags>
void Car<flags>::lockDoors() {
if (flags | AutomicDoorLockingFlag) {
doorElectronic.lockDoors();
} else {
// Do manual door locking
}
}
Wonderful! But the class Car<0> still takes a lot of unnecessary space. So:
Can I somehow include or exclude class members depending on a template parameter?
Other Ideas how to deal with the situation are also welcome!
You want to use policy classes:
class FourDoorPolicy { Door m_doors[4]; ... };
class TwoDoorPolicy { Door m_doors[2]; ... };
class AutoDoorLockingPolicy { ... };
class ManualDoorLockingPolicy { void lockDoors(); ... };
class FourWheelDrivePolicy { TransmissionShafts m_shafts[4]; ... };
class TwoWheelDrivePolicy { TransmissionShafts m_shafts[2]; ... };
template <class DoorPolicy = TwoDoorPolicy,
class LockingPolicy = ManualDoorLockingPolicy,
class DrivePolicy = TwoWheelDrivePolicy>
class Car : public DoorPolicy, public LockingPolicy, public DrivePolicy
{
...
};
Put all the policy specific stuff (e.g. lockDoors() function) inside the policy classes rather than the Car class. The Car class inherits these, which is a form of composition (i.e. you are building all their functionality into the Car class).
Note that you should give all the policy classes a protected, non-virtual destructor so that they can only be instantiated as part of a derived class.
You then instantiate customised cars in the normal template manner:
Car<FourDoorPolicy, AutoDoorLockingPolicy, TwoWheelDrivePolicy> myCar;
Of course, you can use typedefs to help with this (and template aliases in C++0x will help a lot, too).
See: Policy-based Design
You probably should look into Policy-based design. Basically, it consists as externalizing behaviors in policy classes and instantiating a template car object with the appropriate policies. A policy class is responsible for the encapsulation of a given behavior.
From an implementation point of view : Car becomes a template where each type argument corresponds to a given policy (for example : DoorLockingPolicy). Your car template can then be "configured" depending the types you choose to instantiate it with : ManualDoorLockingPolicy or AutomaticDoorLockingPolicy.
template<class DoorLockingPolicy /*, class DoorsPolicy, ... */>
class Car : DoorLockingPolicy
{
public:
void lockDoors()
{
/* ... */
DoorLockingPolicy::lockDoors();
}
};
struct ManualDoorLockingPolicy
{
void lockDoors() { /* ... */ }
};
struct AutomaticDoorLockingPolicy
{
void lockDoors() { /* ... */ }
};
int main()
{
Car<ManualDoorLockingPolicy> car1;
Car<AutomaticDoorLockingPolicy> car2;
}
From a performance point of view, policy-based design is a great way to achieve "don't pay for what you don't use" :
Calls to the policy classes can be inlined and introduce no additional cost
The Car template can inherit privately from its policies and benefit from the empty base optimization.
Once again, Modern C++ Design (Andrei Alexandrescu) is a great read on this topic.
The problem as I see it is that you're trying to define a single class which is capable of representing all possible version of a "Car", meaning that each instance contains member data capable of representing all possible cars. This problem was solved eons ago by traditional inheritance.
Define the functionality common to all cars in the base class. Then derive specific classes which add functionality (and member variables which increase the memory footprint). You minimize your memory simply by instantiating the proper sub class. Each instance contains only the members important to that specific type of Car.
One possibility would be to introduce a feature class. The feature class would have some kind of a unique identifier (I've used int for the hell of it, but boost::uuids::uuid would be more preferable). It does nothing but define a feature of some sort:
class Feature
{
private:
int m_nUniqueID;
protected:
Feature(int _uniqueID) : m_nUniqueID(_uniqueID) {};
virtual ~Feature(){};
public:
const int& getUniqueID const {return(m_nUniqueID);};
}; // eo class Feature
From this, we can derive more concrete features:
class DoorsFeature : public Feature
{
private:
int m_nDoors;
public:
static const int UniqueId;
DoorsFeature(int numDoors) : Feature(UniqueId), m_nDoors(numDoors){};
virtual ~DoorsFeature(){};
void lockDoors() { /* lock the doors */ };
}; // eo class DoorsFeature
class ABSFeature : public Feature
{
public:
static const int UniqueId;
ABSFeature() : Feature(UniqueId){};
virtual ~ABSFeature(){};
}; // eo class ABSFeature
And onwards for any kind of feature that the car can have. Note I would not class wheels as a feature because, well, all cars have wheels although the number may differ. I am referring to various traits that can differ wildly such as electronic doors, ABS, etceteras. Suddenly, your car becomes a much simpler container:
class Car
{
private:
int m_nWheels;
std::string m_Colour;
std::vector<Feature> m_Features;
protected:
public:
Car();
~Car();
void addFeature(Feature& _feature) {m_Features.push_back(_feature);};
Feature getFeature(int _featureId) const;
void lockDoors()
{
DoorsFeature& doorsFeature(static_cast<DoorsFeature&>(getFeature(DoorsFeature::UniqueId)));
doorsFeature.lockDoors();
} // eo lockDoors
}; // eo class Car
Given this, you can also go a step further and introduced named feature-sets (much like the option packs you get from a dealer/manufacturer) that can be automatically applied to a car, or range of makes, models and series.
Obviously, I've left a lot out. You may want to pass a reference to the car to each feature, or do otherwise.
Try rewriting your code to use vector instead of arrays. You can use just the space you need, and it's easier too.
#include <vector>
#include <memory>
class Car
{
public:
int getDoorCount() { return doors.size(); }
bool isFourWheelDrive() { return transmissionShafts.size() == 4; }
bool areDoorsAutoLocking() { return automaticDoorLocking.get() != NULL; }
void lockDoors() {
if (automaticDoorLocking.get() != NULL) {
automaticDoorLocking->lockDoors();
} else {
// Do manual door locking
}
}
private:
std::vector<Door> doors;
std::vector<TransmissionsShafts> transmissionShafts;
std::auto_ptr<DoorLockingElectronic> automaticDoorLocking;
};
Notice how Car now supports hatchbacks (5 doors).

Registering derived classes in C++

EDIT: minor fixes (virtual Print; return mpInstance) following remarks in the answers.
I am trying to create a system in which I can derive a Child class from any Base class, and its implementation should replace the implementation of the base class.
All the objects that create and use the base class objects shouldn't change the way they create or call an object, i.e. should continue calling BaseClass.Create() even when they actually create a Child class.
The Base classes know that they can be overridden, but they do not know the concrete classes that override them.
And I want the registration of all the the Child classes to be done just in one place.
Here is my implementation:
class CAbstractFactory
{
public:
virtual ~CAbstractFactory()=0;
};
template<typename Class>
class CRegisteredClassFactory: public CAbstractFactory
{
public:
~CRegisteredClassFactory(){};
Class* CreateAndGet()
{
pClass = new Class;
return pClass;
}
private:
Class* pClass;
};
// holds info about all the classes that were registered to be overridden
class CRegisteredClasses
{
public:
bool find(const string & sClassName);
CAbstractFactory* GetFactory(const string & sClassName)
{
return mRegisteredClasses[sClassName];
}
void RegisterClass(const string & sClassName, CAbstractFactory* pConcreteFactory);
private:
map<string, CAbstractFactory* > mRegisteredClasses;
};
// Here I hold the data about all the registered classes. I hold statically one object of this class.
// in this example I register a class CChildClass, which will override the implementation of CBaseClass,
// and a class CFooChildClass which will override CFooBaseClass
class RegistrationData
{
public:
void RegisterAll()
{
mRegisteredClasses.RegisterClass("CBaseClass", & mChildClassFactory);
mRegisteredClasses.RegisterClass("CFooBaseClass", & mFooChildClassFactory);
};
CRegisteredClasses* GetRegisteredClasses(){return &mRegisteredClasses;};
private:
CRegisteredClasses mRegisteredClasses;
CRegisteredClassFactory<CChildClass> mChildClassFactory;
CRegisteredClassFactory<CFooChildClass> mFooChildClassFactory;
};
static RegistrationData StaticRegistrationData;
// and here are the base class and the child class
// in the implementation of CBaseClass::Create I check, whether it should be overridden by another class.
class CBaseClass
{
public:
static CBaseClass* Create()
{
CRegisteredClasses* pRegisteredClasses = StaticRegistrationData.GetRegisteredClasses();
if (pRegisteredClasses->find("CBaseClass"))
{
CRegisteredClassFactory<CBaseClass>* pFac =
dynamic_cast<CRegisteredClassFactory<CBaseClass>* >(pRegisteredClasses->GetFactory("CBaseClass"));
mpInstance = pFac->CreateAndGet();
}
else
{
mpInstance = new CBaseClass;
}
return mpInstance;
}
virtual void Print(){cout << "Base" << endl;};
private:
static CBaseClass* mpInstance;
};
class CChildClass : public CBaseClass
{
public:
void Print(){cout << "Child" << endl;};
private:
};
Using this implementation, when I am doing this from some other class:
StaticRegistrationData.RegisterAll();
CBaseClass* b = CBaseClass::Create();
b.Print();
I expect to get "Child" in the output.
What do you think of this design? Did I complicate things too much and it can be done easier? And is it OK that I create a template that inherits from an abstract class?
I had to use dynamic_pointer (didn't compile otherwise) - is it a hint that something is wrong?
Thank you.
This sort of pattern is fairly common. I'm not a C++ expert but in Java you see this everywhere. The dynamic cast appears to be necessary because the compiler can't tell what kind of factory you've stored in the map. To my knowledge there isn't much you can do about that with the current design. It would help to know how these objects are meant to be used. Let me give you an example of how a similar task is accomplished in Java's database library (JDBC):
The system has a DriverManager which knows about JDBC drivers. The drivers have to be registered somehow (the details aren't important); once registered whenever you ask for a database connection you get a Connection object. Normally this object will be an OracleConnection or an MSSQLConnection or something similar, but the client code only sees "Connection". To get a Statement object you say connection.prepareStatement, which returns an object of type PreparedStatement; except that it's really an OraclePreparedStatement or MSSQLPreparedStatement. This is transparent to the client because the factory for Statements is in the Connection, and the factory for Connections is in the DriverManager.
If your classes are similarly related you may want to have a function that returns a specific type of class, much like DriverManager's getConnection method returns a Connection. No casting required.
The other approach you may want to consider is using a factory that has a factory-method for each specific class you need. Then you only need one factory-factory to get an instance of the Factory. Sample (sorry if this isn't proper C++):
class CClassFactory
{
public:
virtual CBaseClass* CreateBase() { return new CBaseClass(); }
virtual CFooBaseClass* CreateFoo() { return new CFooBaseClass();}
}
class CAImplClassFactory : public CClassFactory
{
public:
virtual CBaseClass* CreateBase() { return new CAImplBaseClass(); }
virtual CFooBaseClass* CreateFoo() { return new CAImplFooBaseClass();}
}
class CBImplClassFactory : public CClassFactory // only overrides one method
{
public:
virtual CBaseClass* CreateBase() { return new CBImplBaseClass(); }
}
As for the other comments criticizing the use of inheritance: in my opinion there is no difference between an interface and public inheritance; so go ahead and use classes instead of interfaces wherever it makes sense. Pure Interfaces may be more flexible in the long run but maybe not. Without more details about your class hierarchy it's impossible to say.
Usually, base class/ derived class pattern is used when you have an interface in base class, and that interface is implemented in derived class (IS-A relationship). In your case, the base class does not seem to have any connection with derived class - it may as well be void*.
If there is no connection between base class and derived class, why do you use inheritance? What is the benefit of having a factory if factory's output cannot be used in a general way? You have
class CAbstractFactory
{
public:
virtual ~CAbstractFactory()=0;
};
This is perfectly wrong. A factory has to manufacture something that can be used immediately:
class CAbstractFactory
{
public:
virtual ~CAbstractFactory(){};
public:
CBaseClass* CreateAndGet()
{
pClass = new Class;
return pClass;
}
private:
CBaseClass* pClass;
protected:
CBaseClass *create() = 0;
};
In general, you're mixing inheritance, virtual functions and templates the way they should not be mixed.
Without having read all of the code or gone into the details, it seems like you should've done the following:
make b of type CChildClass,
make CBaseClass::Print a virtual function.
Maybe I'm wrong but I didn't find any return statement in your CBaseClass::Create() method!
Personally, I think this design overuses inheritance.
"I am trying to create a system in which I can derive a Child class from any Base class, and its implementation should replace the implementation of the base class." - I don't know that IS-A relationships should be that flexible.
I wonder if you'd be better off using interfaces (pure virtual classes in C++) and mixin behavior. If I were writing it in Java I'd do this:
public interface Foo
{
void doSomething();
}
public class MixinDemo implements Foo
{
private Foo mixin;
public MixinDemo(Foo f)
{
this.mixin = f;
}
public void doSomething() { this.mixin.doSomething(); }
}
Now I can change the behavior as needed by changing the Foo implementation that I pass to the MixinDemo.