Vivek Goel
Vivek Goel

Reputation: 24140

Avoiding duplication of code in common classes

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

Answers (4)

Jerry Coffin
Jerry Coffin

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

luke
luke

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

Bartek Banachewicz
Bartek Banachewicz

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

Alok Save
Alok Save

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

Related Questions