Reputation: 3011
I would like to understand if there is an 'elegant' way in which one can choose to run a particular (c++) class member function, based on user input.
For example let us say we have a class such that:
class myClass
{
int foo;
myClass(int input) { foo = input;}
void runMyFunction()
{
if ( foo == 1)
{
function1();
}
else if (foo == 2)
{
function2();
}
}
void function1();
void function2();
};
What I would like to do, is that if a user specifies input=1
in the constructor, then function1()
is called when the runMyFunction()
member is called, but if the user had specified input=2
in the constructor, then function2()
should be called instead.
My question is, is there a more elegant way to go this without an if
statement? The impetus is that I would rather not have the code go through this check over and over again, since I will be using this call in a loop. Is there a more elegant way to 'set' which function is going to be called without if
statements in this case? Thanks.
Upvotes: 2
Views: 1898
Reputation: 15334
As Praetorian mentioned in comments you can initialize a member function pointer in the constructor:
class MyClass {
using FuncPtrType = void (MyClass::*)();
FuncPtrType myFunction;
public:
MyClass(int input) {
if (input == 1)
myFunction = &MyClass::function1;
else
myFunction = &MyClass::function2;
}
void runMyFunction() {
(this->*myFunction)();
}
void function1();
void function2();
};
If you find the syntax for member function pointers offensive you could use std::function
:
class MyClass {
std::function<void(MyClass*)> myFunction;
public:
MyClass(int input) {
if (input == 1)
myFunction = &MyClass::function1;
else
myFunction = &MyClass::function2;
}
void runMyFunction() {
myFunction(this);
}
void function1();
void function2();
};
Upvotes: 4
Reputation: 264471
Yes you can use the command pattern. You just need to set up a array of function method pointers.
std::vector<std::function<void()>> actionCommand =
{[](){}, // Zero based index.
[this](){this->function1();},
[this](){this->function2();}
};
void runMyFunction()
{
actionCommand[foo]();
// or
actionCommand.at(foo)(); // throws exception if foo is not in
// correct range.
}
Upvotes: 5
Reputation: 324
You can also use a switch statement. There is a simple tutorial to follow here http://www.tutorialspoint.com/cplusplus/cpp_switch_statement.htm
Put simply, I would do something like this
//while user input not equal to x
// switch (input)
// case A:
function 1();
break;
// case B:
.....
//default:
//this is the case to use if the input doesn't match any of your predefined cases. You might print a warning here, and reprint your answers.
Good luck
Upvotes: 0
Reputation: 184
I don't know if this is elegant or not, but maybe you could have function1 and function2 accept the input, and then the if statements could be placed in function1 and function2, and then execute or just return.
Upvotes: 0