初始化期间运行时 class 方法替换

Runtime class method replacement during initialisation

假设我有一个 class,其中包含一个方法 speak(),它将向终端打印一些内容。它究竟会打印什么是由一个初始化布尔值决定的,如果为真,它将打印"Foo",如果为假,它将打印"Bar"。布尔值的值在运行时确定。

实现这一点的一种方法是在 speak() 函数中添加一个 if 语句,然后调用 foo()bar() 方法。但是,如果经常调用此 class 方法,则可以通过 foo()bar() 函数在 class 初始化。有没有办法使用功能点来实现此功能?

class MyClass
{
  public:
    MyClass (const bool select)
    {
        if (select)
        {
            // Make speak() use foo();
        }
        else
        {
            // Make speak() use bar();
        }
    }

    speak() const;

  private:
    foo() const { std::cout << "Foo\n"; }
    bar() const { std::cout << "Bar\n"; }
}

似乎这种行为是有益的,因此我认为有某种方法可以实现它。但是,我没有找到如何执行此操作的运气,主要是因为我不确定要 google.

感谢您的帮助和建议。

It seems like this kind of behaviour would be beneficial, and therefor I assume there's some way of achieving it.

是的,可以使用成员函数指针。

  1. 声明一个作为成员函数指针的成员变量。

      void (MyClass::*speaker)() const;
    
  2. 在构造函数中适当地初始化它。

    MyClass (const bool select)
    {
       if (select)
       {
          speaker = &MyClass::foo;
       }
       else
       {
          speaker = &MyClass::bar;
       }
    }
    
  3. speak中使用它。

    void speak() const
    {
       (this->*speaker)();
    }
    

http://en.cppreference.com/w/cpp/language/pointer 阅读更多关于成员函数指针的信息。

这里是a working example

#include <iostream>

class MyClass
{
   public:

      MyClass (const bool select)
      {
         if (select)
         {
            speaker = &MyClass::foo;
         }
         else
         {
            speaker = &MyClass::bar;
         }
      }

      void speak() const
      {
         (this->*speaker)();
      }

      void (MyClass::*speaker)() const;

   private:
      void foo() const { std::cout << "Foo\n"; }
      void bar() const { std::cout << "Bar\n"; }
};

int main()
{
   MyClass m1(true);
   MyClass m2(false);

   m1.speak();
   m2.speak();
}

及其输出:

Foo
Bar

存储传递给构造函数的值并在 speak() 中有条件地使用它不只是一个问题吗?

class MyClass
{
  private:
    bool mselect;
  public:
    MyClass (const bool select)
    {
       mselect = select;
    }

    void speak()
    {
        if(mselect)
            std::cout << "Foo\n";
        else
            std::cout << "Bar\n";
    }

};

还是我漏掉了这个问题的一部分?抱歉,将 post 作为评论但还没有声誉。