An idiom for a particular refactoring in c++ - c++

I asked this question :
Best Way to Refactor Class Hierarchy
in such a bad way that I was logically forced to accept the perfectly correct answer. My problem is the following :
I have a class CGrandMother having a public method virtual bool Compute() that does
virtual bool Compute()
{
return false;
}
From CGrandMother derives publicly CMother which does not implement Compute. Now from CMother derive publicly C1 and C2 that do implement virtual bool Compute(). Now virtual bool C1::Compute() and virtual bool C2::Compute() respectively do a lot of stuff proper to respectively C1 and to C2, but also a lot of identical stuff proper to CMother. Now there's a class CFamily having as member a pointer to CMother and almost everywhere in the code Compute is called through lines of the form
ptrCMother->Compute();
I want to factor out the common stuff related to CMother done in C1 and C2 so that I wouldn't have to change all those ptrCMother->Compute();. Of course I can create a member function in CMother doing it, and call the latter in bool C1::Compute() and bool C2::Compute(). But...
In c++, if you have B deriving from A, A::dostuff() and B::dostuff() and if p points to a type B then p->dostuff() will execute B::dostuff() by polymorphism. I would like to know if there's an idiom/pattern allowing me to achieve this : "p->dostuff()" will execute "A::dostuff()" or not (according to a bool let's say) and then "B::dostuff()", which does of course not happen in c++ for class member functions that are non constructors etc.
To be clear : base method is not called before its corresponding derived method is called by indirection. Is there an idiom/pattern allowing make base method being called (or not, according to a bool) before its corresponding derived method ?

What's wrong with the solution that you mentioned, consisting in creating a method in the CMother class that is called by its children?
#include <iostream>
#include <memory>
using namespace std;
class CGrandMother
{
private:
virtual bool _Compute()
{
return false;
}
public:
bool Compute()
{
return _Compute();
}
};
class CMother : public CGrandMother
{
protected:
void _CommonStuff()
{
cout << "work common to children" << endl;
}
};
class C1 : public CMother
{
private:
virtual bool _Compute() override
{
_CommonStuff();
cout << "work specific to C1" << endl;
return true;
}
};
class C2 : public CMother
{
private:
virtual bool _Compute() override
{
_CommonStuff();
cout << "work specific to C2" << endl;
return true;
}
};
int main() {
unique_ptr<CMother> c1(new C1);
unique_ptr<CMother> c2(new C2);
c1->Compute();
c2->Compute();
return 0;
}
Notice that I've restrained the access modifiers of my classes:
There is no public virtual function, following the Non-Virtual Interface pattern. A function that is both public and virtual has two jobs: It defines an interface and an implementation, and often ends up being bad at both.
The method _CommonStuff() is protected, so that it is not visible to the rest of the world but still callable by subclasses
Also, you make CMother inherit publicly from CGrandMother, which means that a CMother is a CGrandMother. Is that really true?
Note also that if CMother was the head of the hierarchy, then you could have called _CommonStuff() through its public (but non virtual!) Compute method, and all the subclasses would automatically call _CommonStuff() too. That's one of the great things about this pattern: You can easily make your Compute() method do work that is common to all the subclasses, check invariants, etc
This would look like that: https://ideone.com/vXd4fL
I removed CGrandMother, and CMother is now the head of my hierarchy. In its public method Compute(), I call _CommonStuff(). The children only have to implement _Compute(). _CommonStuff() will be called automatically by all children when they call Compute().

Related

Making this code properly polymorphic

I have an abstract class Parent, which has multiple children and blank functions for interacting with each of these children. Each Child overrides Parent's functions and interacts with other Childs in different ways; i.e. Child1 has different implementations for interact_with(Child1), interact_with(Child2), etc etc.
In Parent, I have a function interact_with(Parent foo). Every Child looking to interact with another Child must pass through this function first. Until now everything is good, but then we run into a problem: after some basic logic has been processed, the Child then needs to know the specific type of its parameter so it can go on and call its own overridden function. At the moment I have this:
Child1* child1 = dynamic_cast<Child1*>(foo);
Child2* child2 = dynamic_cast<Child2*>(foo);
Child3* child3 = dynamic_cast<Child3*>(foo);
if(child1 != nullptr){
interact_with(child1)
}
else if(child2 != nullptr){
interact_with(child2)
}
else if(child3 != nullptr){
interact_with(child3)
}
It works, but it isn't a very good solution. It gets especially bad when I have so many classes. Is this indicative of flawed base design, and if so, how would I improve this?
EDIT: To clarify: I have something like this
//Parent is an abstract class
class Parent
{
void interact_with(Parent* foo){
//this is here because there is a lengthy code segment
//that needs to be run no matter what child interacts
//with which
//afterwards, I need to interact with whatever foo really is
}
virtual void interact_with(Child1* child){*blank*};
virtual void interact_with(Child2* child){*blank*};
virtual void interact_with(Child3) child){*blank*};
};
class Child1 : public Parent
{
virtual void interact_with(Child1* child){*do something*};
virtual void interact_with(Child2* child){*do something else*};
virtual void interact_with(Child3* child){*do something else*};
};
Already.
The #imreal answer using double dispatch is correct. However, the dispatches can be done using virtual member functions instead of a map and function pointers (which is actually similar to the vtable the compiler generates).
The problem is that a single virtual function will not solve the problem, because you really need a double dispatch (i.e. a virtual call regarding both objects, not just the one being called).
See the following working example:
#include <iostream>
class Child1;
class Child2;
class Parent
{
public:
virtual void interact_with(Parent* other) = 0;
virtual void interact_with(Child1* child) {};
virtual void interact_with(Child2* child) {};
};
class Child1 : public Parent
{
public:
virtual void interact_with(Parent* other)
{
other->interact_with(this);
}
virtual void interact_with(Child1* child)
{
std::cout << "Child1 - Child1\n";
}
virtual void interact_with(Child2* child)
{
std::cout << "Child1 - Child2\n";
}
};
class Child2 : public Parent
{
public:
virtual void interact_with(Parent* other)
{
other->interact_with(this);
}
virtual void interact_with(Child1* child)
{
std::cout << "Child2 - Child1\n";
}
virtual void interact_with(Child2* child)
{
std::cout << "Child2 - Child2\n";
}
};
int main()
{
Child1 c1;
Parent* p1 = &c1; // upcast to parent, from p1, we don't know the child type
Child2 c2;
Parent* p2 = &c2;
c1.interact_with(&c2); // single virtual call to Child1 - Child2
p1->interact_with(&c2); // single virtual call to Child1 - Child2
p1->interact_with(p2); // double virtual call to Child2 - Child1 (NB: reversed interaction)
}
It outputs:
Child1 - Child2
Child1 - Child2
Child2 - Child1
Note the last one is reversed. That's because to make the dynamic dispatch using virtual functions on the argument, I have to swap the this pointer with the argument. This is fine if these interactions are symmetric. If they aren't, then I'd suggest to create a wrapper around the most generic one swapping the this and the argument again.
Warning: this solution will break your interfaces. But don't worry, they are already broken ;)
In my opinion your design mistake is following: although all children are "equal" you pick one of them to be responsible for interactions and call a method on it (And if you want 3, 4, ..., N equal children (in an array) to interact simultaneously, which one is responsible?)
If in your application all objects are equally important and no object is responsible for interactions, you should move interactions into free overloaded binary functions:
void interact(Child1* a, Child1* b);
void interact(Child1* a, Child2* b);
...
void interact(Child2* a, Child1* b)
{
interact(b, a); // if order does not matter, reuse another function
}
Clearly, it won't solve the problem of boilerplate code, but at least it could help you to re-think your design and to find a better solution than double dispatch or casting.
Also, depending on functions internals, you could probably reduce writing (but not code size) easily by using template functions instead of overloaded ones.
Using dynamic_cast<> like that is bad design like you said. You should make the function interact_with virtual like this in the declaration.
virtual void interact_with(Parent foo);
This will make the method call use the subclass's implementation of interact_with instead of the parent class's. You can then replace everything you've written with just this.
interact_with(foo);
Here is a pretty good explanation of virtual methods.
What you want is double dispatch
There are many approaches that you might take depending on your requirements. A very generic one is having a simple map of the form Key(type, type) -> Value(function) that associates an argument type pair with the function to be called.
In this case you will need a set of free functions of the type void function(Parent*, Parent*) (one for every combination you need) and a map of the type std::unordered_map<std::pair<TypeId, TypeId>, FunctionType> where TypeId is some form of type identifier with value semantics.
Then you do the dispatch at runtime:
if(map_.find(make_pair(type1, type2)) != map_.end())
map_[make_pair(type1, type2)](obj1, obj2);
Not before registering each function:
map_[make_pair(type1, type2)] = func12;
map_[make_pair(type2, type3)] = func23;
....

oop - C++ - Proper way to implement type-specific behavior?

Let's say I have a parent class, Arbitrary, and two child classes, Foo and Bar. I'm trying to implement a function to insert any Arbitrary object into a database, however, since the child classes contain data specific to those classes, I need to perform slightly different operations depending on the type.
Coming into C++ from Java/C#, my first instinct was to have a function that takes the parent as the parameter use something like instanceof and some if statements to handle child-class-specific behavior.
Pseudocode:
void someClass(Arbitrary obj){
obj.doSomething(); //a member function from the parent class
//more operations based on parent class
if(obj instanceof Foo){
//do Foo specific stuff
}
if(obj instanceof Bar){
//do Bar specific stuff
}
}
However, after looking into how to implement this in C++, the general consensus seemed to be that this is poor design.
If you have to use instanceof, there is, in most cases, something wrong with your design. – mslot
I considered the possibility of overloading the function with each type, but that would seemingly lead to code duplication. And, I would still end up needing to handle the child-specific behavior in the parent class, so that wouldn't solve the problem anyway.
So, my question is, what's the better way of performing operations that where all parent and child classes should be accepted as input, but in which behavior is dictated by the object type?
First, you want to take your Arbitrary by pointer or reference, otherwise you will slice off the derived class. Next, sounds like a case of a virtual method.
void someClass(Arbitrary* obj) {
obj->insertIntoDB();
}
where:
class Arbitrary {
public:
virtual ~Arbitrary();
virtual void insertIntoDB() = 0;
};
So that the subclasses can provide specific overrides:
class Foo : public Arbitrary {
public:
void insertIntoDB() override
// ^^^ if C++11
{
// do Foo-specific insertion here
}
};
Now there might be some common functionality in this insertion between Foo and Bar... so you should put that as a protected method in Arbitrary. protected so that both Foo and Bar have access to it but someClass() doesn't.
In my opinion, if at any place you need to write
if( is_instance_of(Derived1) )
//do something
else if ( is_instance_of(Derived2) )
//do somthing else
...
then it's as sign of bad design. First and most straight forward issue is that of "Maintainence". You have to take care in case further derivation happens. However, sometimes it's necessary. for e.g if your all classes are part of some library. In other cases you should avoid this coding as far as possible.
Most often you can remove the need to check for specific instance by introducing some new classes in the hierarchy. For e.g :-
class BankAccount {};
class SavingAccount : public BankAccount { void creditInterest(); };
class CheckingAccount : public BankAccount { void creditInterest(): };
In this case, there seems to be a need for if/else statement to check for actual object as there is no corresponsing creditInterest() in BanAccount class. However, indroducing a new class could obviate the need for that checking.
class BankAccount {};
class InterestBearingAccount : public BankAccount { void creditInterest(): } {};
class SavingAccount : public InterestBearingAccount { void creditInterest(): };
class CheckingAccount : public InterestBearingAccount { void creditInterest(): };
The issue here is that this will arguably violate SOLID design principles, given that any extension in the number of mapped classes would require new branches in the if statement, otherwise the existing dispatch method will fail (it won't work with any subclass, just those it knows about).
What you are describing looks well suited to inheritance polymorphicism - each of Arbitrary (base), Foo and Bar can take on the concerns of its own fields.
There is likely to be some common database plumbing which can be DRY'd up the base method.
class Arbitrary { // Your base class
protected:
virtual void mapFields(DbCommand& dbCommand) {
// Map the base fields here
}
public:
void saveToDatabase() { // External caller invokes this on any subclass
openConnection();
DbCommand& command = createDbCommand();
mapFields(command); // Polymorphic call
executeDbTransaction(command);
}
}
class Foo : public Arbitrary {
protected: // Hide implementation external parties
virtual void mapFields(DbCommand& dbCommand) {
Arbitrary::mapFields();
// Map Foo specific fields here
}
}
class Bar : public Arbitrary {
protected:
virtual void mapFields(DbCommand& dbCommand) {
Arbitrary::mapFields();
// Map Bar specific fields here
}
}
If the base class, Arbitrary itself cannot exist in isolation, it should also be marked as abstract.
As StuartLC pointed out, the current design violates the SOLID principles. However, both his answer and Barry's answer has strong coupling with the database, which I do not like (should Arbitrary really need to know about the database?). I would suggest that you make some additional abstraction, and make the database operations independent of the the data types.
One possible implementation may be like:
class Arbitrary {
public:
virtual std::string serialize();
static Arbitrary* deserialize();
};
Your database-related would be like (please notice that the parameter form Arbitrary obj is wrong and can truncate the object):
void someMethod(const Arbitrary& obj)
{
// ...
db.insert(obj.serialize());
}
You can retrieve the string from the database later and deserialize into a suitable object.
So, my question is, what's the better way of performing operations
that where all parent and child classes should be accepted as input,
but in which behavior is dictated by the object type?
You can use Visitor pattern.
#include <iostream>
using namespace std;
class Arbitrary;
class Foo;
class Bar;
class ArbitraryVisitor
{
public:
virtual void visitParent(Arbitrary& m) {};
virtual void visitFoo(Foo& vm) {};
virtual void visitBar(Bar& vm) {};
};
class Arbitrary
{
public:
virtual void DoSomething()
{
cout<<"do Parent specific stuff"<<endl;
}
virtual void accept(ArbitraryVisitor& v)
{
v.visitParent(*this);
}
};
class Foo: public Arbitrary
{
public:
virtual void DoSomething()
{
cout<<"do Foo specific stuff"<<endl;
}
virtual void accept(ArbitraryVisitor& v)
{
v.visitFoo(*this);
}
};
class Bar: public Arbitrary
{
public:
virtual void DoSomething()
{
cout<<"do Bar specific stuff"<<endl;
}
virtual void accept(ArbitraryVisitor& v)
{
v.visitBar(*this);
}
};
class SetArbitaryVisitor : public ArbitraryVisitor
{
void visitParent(Arbitrary& vm)
{
vm.DoSomething();
}
void visitFoo(Foo& vm)
{
vm.DoSomething();
}
void visitBar(Bar& vm)
{
vm.DoSomething();
}
};
int main()
{
Arbitrary *arb = new Foo();
SetArbitaryVisitor scv;
arb->accept(scv);
}

C++ private and protected virtual method

It seems that it is good to make the virtual methods private in order to separate the interfaces for following two clients -
1. clients that instantiate an object and call the method
2. clients that derive from the class and may want to override the method.
Simply put - the first client does not need to know if a method is virtual. He will call the base class public non-virtual method which in turn will call the private virtual method. See code below for example.
Now in the case where the virtual method needs to super-message its base class' corresponding virtual method such as say a Save method - which has to pass through all virtual methods in the chain of inheritance in order to save data corresponding to each level of derivation - we have no option but to use a protected virtual method - unless there is a way to guarantee saving of data at all levels of derivation without using super messaging (there is none that I know).
I would like to know if above reasoning correct.
Make sure you use the scroll to see the entire code.
#include <iostream>
using namespace std;
class A {
string data;
protected:
virtual void SaveData()= 0;
public:
A():data("Data of A"){}
void Save(){
cout << data << endl;
SaveData();
}
};
class B : public A {
string data;
protected:
virtual void SaveData() { cout << data << endl;}
public:
B():data("Data of B") {}
};
class C : public B {
string data;
protected:
virtual void SaveData() {
B::SaveData();
cout << data << endl;
}
public:
C():data("Data of C") {}
};
int main(int argc, const char * argv[])
{
C c;
c.Save();
return 0;
}
Yes, if you need to call the SaveData of another class, it needs to be accessible from that class - so public or protected.
You are exactly right:
NVI (Non-Virtual Interface) requires that virtual methods not be public
Calling the base class method requires that it not private
therefore protected is the obvious solution, at least in C++03. Unfortunately it means you have to trust the derived class developer not to forget to call "super".
In C++11, you can use final to prevent a derived class from overriding a virtual method; it means though that you are forced to introduce a new hook, example:
class Base {
public:
void save() {
// do something
this->saveImpl();
// do something
}
private:
virtual void saveImpl() {}
};
class Child: public Base {
private:
virtual void saveImpl() final {
// do something
this->saveImpl2();
// do something
}
virtual void saveImpl2() {}
};
Of course, there is the trouble of having to come up with a new name each and every time... but at least you are guaranteed that Child::saveImpl will be called because none of its children can override it.
It's difficult to tell what you're asking, but from the example, you do not need to make the method protected. It actually can be private. For details about the subtleties see this post: What is the point of a private pure virtual function?.
So long as you're not calling the private member from derived class (or outside classes), you're ok. Overriding of private members is ok. It does sound quite naughty and wrong that you can override your parent's privates, but in c++ you're allowed to do this.
The following should be ok:
#include <iostream>
using namespace std;
class A {
string data;
private:
virtual void SaveData()= 0;
public:
A():data("Data of A"){}
void Save(){
cout << data << endl;
SaveData();
}
};
class B : public A {
string data;
private:
virtual void SaveData() { cout << data << endl;}
public:
B():data("Data of B") {}
};

Special interaction between derived objects (i.e. mutiple dispatch)

So, I have a list of base class pointers:
list<Base*> stuff;
Then, at some point one of the objects will look through all other objects.
Base * obj = ...; // A pointer from the 'stuff'-list.
for (list<Base*>::iterator it = stuff.begin(); it != stuff.end(); it++)
{
if (obj == *it)
continue;
// Problem scenario is here
obj->interact(it);
}
What I want to achieve is that depending on what derived typeobj and *it are, they will interact differently with each other, i.e. DerivedA will destroy itself if it's interacting with DerivedB, but only if DerivedB has set the property bool c = true;. So something like:
struct Base
{
virtual void interact(Base * b); // is always called
};
struct DerivedA : public Base
{
virtual void interact(Base * b){} // is never called
virtual void interact(DerivedB * b) // is never called
{
if (b->c)
delete this;
}
};
struct DerivedB : public Base
{
bool c = false;
virtual void interact(Base * b){} // is never called
virtual void interact(DerivedA * a) // is never called
{
c = true;
}
};
// and many many more Derived classes with many many more specific behaviors.
At compile time, they are both Base-pointers and will not be able to call each other and expect the type to magically appear. If this was a one way relation, i.e. I knew what type of one of them, I could use the Visitor pattern. I believe I should use some kind of Mediator pattern but can't really figure out how since the mediator too will hold Base-pointers and thus it won't make a difference.
I haven't got a clue on how to continue... anyone?
Background:
I'm creating a game, this problem originates from the Room class who keeps track of it's contents, i.e. what GameObjects are currently in the room.
Sometimes, an object moves (for example, the player). The room will then loop over all objects that are on the soon-to-be-moved-upon floor tile (the loop above) and will check if the objects will interact with eachother.
For example, if it's a Troll the Player would want to hurt it. Or he would just like to hurt any Character (both Troll and Player are derived from Character) that originates from any another "team" (which can be accessed from the function getAlignment(), which all Characters implement).
If you can, grab a copy of "More Effective C++", and have a look at item #31 which is about implementing multiple dispatch, which is basically what you're looking for here. Meyers discusses several approaches to the problem and their various trade-offs. (He even uses a game as an example.)
Perhaps the best advice he gives, however, is to try and redesign your code to avoid requiring this facility. In the text, a non-member function approach is also explored, which has the added bonus of eliminating the question of to which object each function describing an interaction should belong.
I think your suggested idea (with the Base::interact) function is almost complete. It seems that the only missing part is this:
In your Base, you need to have all the interact overloads for the sub-types. Consider this extension to your Base structure:
struct DerivedA;
struct DerivedB;
struct Base
{
virtual void interact(Base * b); // *<->Base interaction
virtual void interact(DerivedA * da); // *<->DerivedA interaction
virtual void interact(DerivedB * db); // *<->DerivedB interaction
};
This is a painful thing about implementing double-dispatch in C++: if you add a new sub-type, you have to touch the base of the hierarchy.
you will need to implement all possible combinations of types interacting with each other as virtual functions on top of hierarchy.
Here's an example that tests all possible interactions:
#include<iostream>
void say(const char *s){std::cout<<s<<std::endl;}
struct DerivedA;
struct DerivedB;
struct Base{
virtual void interact(Base *b) = 0;
virtual void interactA(DerivedA *b) = 0;
virtual void interactB(DerivedB *b) = 0;
};
struct DerivedA : public Base
{
virtual void interact(Base *b){
b->interactA( this );
}
virtual void interactA(DerivedA *b){
say("A:A");
}
virtual void interactB(DerivedB *b){
say("A:B");
}
};
struct DerivedB:public Base{
virtual void interact(Base *b){
b->interactB( this );
}
virtual void interactA(DerivedA *b){
say("B:A");
}
virtual void interactB(DerivedB *b){
say("B:B");
}
};
void interact(Base *b1,Base *b2){
b1->interact( b2 );
}
main(){
Base *a = new DerivedA;
Base *b = new DerivedB();
interact(a,b);
interact(b,a);
interact(a,a);
interact(b,b);
}
First: Why do you use struct instead of class?
Second: If you use class instead of struct you could (must) do something like this:
class Base
{
virtual void interact(Base * b); // see the VIRTUAL word (explained down)
};
class DerivedA : public Base
{
virtual void interact(DerivedB * b)
{
if (b->c)
delete this;
}
};
class DerivedB : public Base
{
bool c = false;
virtual void interact(DerivedA * a)
{
c = true;
}
};
Using virtual keyword is wath you need (I guess). If you define a method as virtual you are telling "Hey! this maybe has been override someplace" so.. when you code this:
DerivedA* a = new DerivedA();
DerivedB* b = new DerivedB();
a.interact(b); // here instead of calling Base::interact(Base*) call the override method in DerivedA class (because is virtual)
EDIT:
Forget that answer.. (didn't see the comment of the virtual)
EDIT 2:
Please, see catwalk and Frerich Raabe answers.
Your interact() functions don't have the same signature: In the derived classes they should also be
virtual void interact(Base * b);
The virtual is optional, of course, but for clarity I'd put it in there.
To find out whether DerivedA::interact() should do something with it's parameter, you can implement another virtual functions in your base class:
virtual canDoX(Base * b);
virtual canDoY(Base * b);
Then in the derived implementations it could look like this:
// DerivedA
void interact(Base * b)
{
if (b->canDoX() && b->c)
delete this;
}
// DerivedB
void interact(Base * b)
{
if(b->canDoY())
c = true;
}
Update:
Since you liked Frerich Raabe's answer, let me explain why I think my approach is a bit better.
Following his advice, one has to create an interact() method for each derived class in the base and all other derived classes that can interact with a certain class.
With my solution one would have to add methods for certain properties, that can also be combined.
If you have a Troll it would return true in its canBeKilled() method. An apple canBeEaten() and a tasty wild animal canBeKilled() and then canBeEaten().
If you can combine the properties, you have to add fewer functions.
Furthermore: If the troll drank some elixir making it invulnerable for a period of time, it returns canBeKilled() == false and that's it. You don't have to check the isInvulnerable() flag in each other interacting class.
I think your problem is well discussed in
Scott Meyer's Effective C++ which is like as follows:
Rule : Don't try access array of derived class objects using base class pointer -->the result would be undefined.
I will give you an example of it:
struct Base{
virtual void print() { //in base }
virtual ~Base() {} //
}
struct Derived : public Base {
virtual void print(){ //in derived }
}
void foo(Base *pBase,int N)
{
for(int i=0; i<N ; i++)
pBase[i].print(); // result will be undefined......
}
int main()
{
Derived d[5];
foo(&d,5);
}
The reason for it such behaviour is that compiler find next elements at the jump of sizeof(Base) bytes....
I think you got my point....

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.