I am slightly confused with what I read in the post: case-vs-if-else-if-which-is-more-efficient
It is suggested many times that long case/if-else statements should be replaced with the use of polymorphism. I am trying to get my head around what that really means. How can you replace:
case TASK_A:
// do things for task A
break;
case TASK_B:
// do things for task B
break;
:
:
case TASK_J:
// do things for task J
break;
With polymorphism? I could sort-of understand it if the "do ..." part is basically the same repetition, but if there is significant differences between some or all of the "cases" then does this still apply?
In the example you link to, the switch
is over the type of an object, and the suggestion is to use polymorphism to remove the need to check the type. That is, declare a virtual function in the base class, override it for each concrete class to do whatever needs doing, and replace the entire switch
with a call to that function.
In your case, you're testing the value of a variable, not the type of an object. However, you could transform it to a polymorphic solution if you wanted:
struct Task {virtual void do_things() = 0;};
struct TaskA : Task {virtual void do_things() {/*do things for task A*/}};
struct TaskB : Task {virtual void do_things() {/*do things for task B*/}};
//...
struct TaskJ : Task {virtual void do_things() {/*do things for task J*/}};
Then you could replace the variable you're switching over with a (smart) pointer to Task
; and the switch with task->do_things()
. Whether that's better than a switch
is a matter of taste.
You create a parent class/interface, e.g. task
which defines a function (potentially abstract) that child classes override; let's call this function handle_task
You then create a child class for each type of task (i.e. each case
statement above) and put the // do things for task X
in that classes' implementation of handle_task
Due to polymorphism, each of these child classes can be passed around as / treated as instances of the parent class, and when you call handle_task
on them the correct code will be executed.
A quick worked example:
#include <iostream>
class Task {
public:
virtual void handle_task()
{
std::cout << "Parent task" << std::endl;
}
};
class Task_A: public Task {
public:
void handle_task()
{
std::cout << "task a" << std::endl;
}
};
class Task_B: public Task {
public:
void handle_task()
{
std::cout << "task b" << std::endl;
}
};
int main( void )
{
Task *task;
Task_A a;
Task_B b;
task=&a;
task->handle_task();
task=&b;
task->handle_task();
}
Will print
/tmp$ g++ test.cpp
/tmp$ ./a.out
task a
task b
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With