在 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::functionstd::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是否在不加花括号的情况下也是一个复合语句

c++如何在不改变输入顺序的情况下去重输出?

c++中for循环和switch语句哪个更高效

如何在不接触该目录中的文件的情况下查找文件夹更改(使用 Windows 和 C++)

如何在 JavaScript 中编写没有“else”的 IF else 语句 [关闭]

如何在构造函数中访问类变量以在不使用 C++ 中的 this 指针的情况下分配它们