【问题标题】:In C++, how to choose to run a specific member function without using if-statements?在 C++ 中,如何在不使用 if 语句的情况下选择运行特定的成员函数?
【发布时间】: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::bindlambda expressions 而不是函数指针,而成员函数指针更糟糕。

标签: c++ class if-statement constructor member


【解决方案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 语句吗?我不希望这种情况发生。
      • 是的,我错过了你问题的那一部分。在这种情况下,您需要参考其中一个答案。也许研究一下命令模式,虽然它有点复杂。
      猜你喜欢
      • 2019-08-11
      • 1970-01-01
      • 2017-02-27
      • 1970-01-01
      • 2016-04-18
      • 2021-11-24
      • 2017-10-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多