Вопрос:

Замена метода класса времени выполнения во время инициализации

c++ methods initialization function-pointers member-function-pointers

34 просмотра

2 ответа

69 Репутация автора

Скажем, у меня есть класс, который содержит метод, speak()который будет печатать что-то в терминал. Что именно он будет распечатывать, определяется логическим значением инициализации, если true, он напечатает «Foo», если false, он напечатает «Bar». Значение логического значения определяется во время выполнения.

Один из способов реализовать это - добавить ifв speak()функцию оператор, который затем вызвал бы метод foo()или bar(). Однако, если этот метод класса вызывался часто, то ifможно было бы избежать переключения и вызова дополнительной функции, заменив speak()функцию вместо функции foo()или bar()функцией или при инициализации класса. Есть ли способ достичь этой функциональности, используя, возможно, функциональные точки?

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.

Спасибо за вашу помощь и совет.

Автор: Arc Источник Размещён: 08.11.2017 10:36

Ответы (2)


3 плюса

178764 Репутация автора

Решение

Кажется, что такое поведение было бы полезным, и поэтому я предполагаю, что есть какой-то способ достичь этого.

Да, это возможно с помощью указателя на функцию-член.

  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 .

Вот рабочий пример :

#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
Автор: R Sahu Размещён: 08.11.2017 10:54

0 плюса

36 Репутация автора

Разве это не просто вопрос сохранения значения, переданного конструктору, и использования его в условном выражении в 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";
    }

};

Или я пропускаю какую-то часть этой проблемы? Извините, опубликовал бы как комментарий, но не имеет репутации.

Автор: user1139455 Размещён: 08.11.2017 10:59
Вопросы из категории :
32x32