在 C++ 中,如何在不使用 if 语句的情况下选择运行特定的成员函数?
Posted
技术标签:
【中文标题】在 C++ 中,如何在不使用 if 语句的情况下选择运行特定的成员函数?【英文标题】:In C++, how to choose to run a specific member function without using if-statements? 【发布时间】:2015-05-15 20:50:31 【问题描述】:我想了解是否有一种“优雅”的方式可以根据用户输入选择运行特定的 (c++) 类成员函数。
例如,假设我们有一个这样的类:
class myClass
int foo;
myClass(int input) foo = input;
void runMyFunction()
if ( foo == 1)
function1();
else if (foo == 2)
function2();
void function1();
void function2();
;
我想做的是,如果用户在构造函数中指定input=1
,则在调用runMyFunction()
成员时调用function1()
,但如果用户在构造函数中指定了input=2
,然后应该调用function2()
。
我的问题是,如果没有 if
声明,有没有更优雅的方法?动力是我不想让代码一遍又一遍地通过这个检查,因为我将在循环中使用这个调用。在这种情况下,是否有一种更优雅的方式来“设置”在没有if
语句的情况下将调用哪个函数?谢谢。
【问题讨论】:
你对函数指针感到满意吗? 您可以使用std:map
,其中键是可能的用户输入,值是您要执行的功能。
@Beta 我没用过,但如果这是个好方法,我现在愿意学习。
@Learnaholic 您的条件是在编译时评估,还是在运行时评估?
这些天使用现代编译器,我建议阅读 std::function
、std::bind
和 lambda expressions 而不是函数指针,而成员函数指针更糟糕。
【参考方案1】:
是的,您可以使用命令模式。 你只需要设置一个函数方法指针数组。
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.
【讨论】:
谢谢,但是如何在类中定义actionCommand[1] VS actionCommand[2]?我不清楚如何在这种特殊性中使用它,以及所涉及的班级成员是什么。 @Learnaholic:有帮助。 有点是的,这对我来说是新的,所以我需要学习这个。我想弄清楚的是你在这里拥有的 actionCommand 函数在我的类结构中的什么位置?谢谢。 @Learnaholic:actionCommand
是您对象的普通成员。只需将其放在您的声明上方即可foo
@Learnaholic:因为您在构造函数中设置了foo
。您可以只使用一个变量来表示您在构造函数中初始化的函数。因此,在 runMyFunction()
中没有运行时 switch
,而是在初始化这个变量的构造函数中有一个 switch
。由于您现在在变量中拥有该函数,因此您可以调用它。【参考方案2】:
正如Praetorian在cmets中提到的,你可以在构造函数中初始化一个成员函数指针:
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();
;
如果您发现成员函数指针的语法令人反感,您可以使用 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();
;
【讨论】:
【参考方案3】:我不知道这是否优雅,但也许你可以让function1和function2接受输入,然后if语句可以放在function1和function2中,然后执行或只是返回。
【讨论】:
【参考方案4】:您也可以使用 switch 语句。这里有一个简单的教程http://www.tutorialspoint.com/cplusplus/cpp_switch_statement.htm
简单地说,我会做这样的事情
//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.
祝你好运
【讨论】:
是的,但是不会在循环中每次都评估 switch 语句吗?我不希望这种情况发生。 是的,我错过了你问题的那一部分。在这种情况下,您需要参考其中一个答案。也许研究一下命令模式,虽然它有点复杂。以上是关于在 C++ 中,如何在不使用 if 语句的情况下选择运行特定的成员函数?的主要内容,如果未能解决你的问题,请参考以下文章
在C语言中,if和else if是否在不加花括号的情况下也是一个复合语句
如何在不接触该目录中的文件的情况下查找文件夹更改(使用 Windows 和 C++)