Reputation: 24140
I have a callback function called as
MyCallBack(int type)
and I have 3 classes B,C and D derived from A having common methods name Currently my code is like this
MyCallBack(int type){
if(type == 1 ){
B b;
b.perform();
}else if(type==2) {
C c;
c.perform();
}else if(type ==3){
D d;
d.perform();
}
Is there a way I can reduce this code something like
MyCallBack(int type){
Common object(type);
object.perform();
}
Upvotes: 2
Views: 137
Reputation: 490018
@Als' idea of using polymorphism is a good one (IMO), but it only really works after you've converted from your input integer to an actual type. One way to do that would be to index into an array of pointers to objects:
MyCallback(int type) {
static A *ptrs[] = { new B, new C, new D};
ptrs[type-1]->perform();
}
Edit: just in case you weren't aware, for this to work correctly, perform
needs to be a virtual function declared (probably as pure) virtual in A
, and defined in each of B
, C
, and D
. You need to ensure that the whole signature of the function, not just the name, is the same between the classes.
Upvotes: 2
Reputation: 37433
How about an interface?
class A
{
public:
virtual void perform() = 0;
};
class B : public A
{
public:
void perform() { ... }
};
// Same for C, and D
so your callback would then look like:
MyCallBack(A& performer)
{
performer.perform();
}
If you can't change the signature of the callback, how about the abstract factory pattern:
function A* AFactory(int type)
{
switch(type)
{
case 1: return new B(); // Assuming B, C, D all derive from A
case 2: return new C();
case 3: return new D();
default: return nullptr; // nullptr is a c++11 thing. Use NULL, if you're still on C++03
}
}
and then the callback...
MyCallBack(int type)
{
std::unique_ptr<A> obj(AFactory(type)); // this will automatically release the memory once it falls out of scope
obj->perform();
}
Upvotes: 1
Reputation: 39370
You should create Object Factory or just static(global) method returning pointer (or reference, maybe) to base type, but consisting object of derived type.
CBase* CreateObjectBasedOnType(int type)
{
// check for type and return appriopriate derived object
}
MyCallBack(int type)
{
CreateObjectBasedOnType(type)->perform();
}
Note that methods you want to call should be virtual.
Even better way could use templates
template<typename T>
MyCallBack()
{
T Obj;
Obj.perform();
}
Upvotes: -1
Reputation: 206508
Basically, What you need is Polymorphism.
All your classes B
,C
,D
should derive from a Abstract class say SuperBase
with a pure virtual method perform()
.
Your code should use only a pointer to SuperBase
which contains address of actual concrete class object.
Once you have this in place, depending on actual type of the object being pointed the method from appropriate class would be called.
The advantage of this method is there is No hardcoded type checking & also flexibility of a loosely coupled design using Open Closed principle.
Upvotes: 3