Передать указатель функции во вложенный класс

#c #function #pointers

#c #функция #указатели

Вопрос:

У меня есть вложенный класс B внутри класса A . Мне нужно передать пользовательскую функцию с одним целочисленным аргументом и вернуть тип void во время выполнения в класс B.

Вот как я пытался это сделать. Сначала я передал функцию через конструктор A. А затем, чтобы передать его в B, я попытался использовать указатель на функцию-член. Однако я не могу понять, как вызвать функцию foo() внутри doStuff() .

 class A {
    void(*f)(int);
    A(void(*f)(int)) : f(f) {};
    class B {
       void(*A::*foo)(int) = amp;A::f;
       void doStuff() {
          var = 10;
          *foo(var); //Doesn't work
       } 
    };
};

void testFunction(int a) {
     //do something
}

A a(testFunction);
  

Как правильно его вызвать? И имеет ли это решение смысл в целом?

Редактировать: возможное альтернативное решение:

 class A {
  A(void(*f)(int)) {
     b = B(f);
  }
  class B {
    void(*f)(int);
    B() {}
    B(void(*f)(int)) : f(f) {}
    
    void doStuff() {
        var = 10;
        f(10);
    }
   };
   B b;
};
  

Комментарии:

1. Почему бы просто не передать указатель на функцию ctor B?

2. Удобное чтение: isocpp.org/wiki/faq/pointers-to-members Но также читайте об std::function этом .

3. @StephenNewell Должен ли я создавать объект B для этого? Я хотел бы исключительно инициировать объект A, подобный этому A a(testFunction) , и передать функцию в B, без необходимости создавать объект B.

4. @LennyWhite Do I have to create object of B for that? В том виде, в каком он у вас есть сейчас, вы должны B так или иначе создать объект типа, потому doStuff что это функция-член B , и для ее вызова вам нужен экземпляр B . Обратите внимание, что создание объекта A a; не создает никакого экземпляра B объекта. class B является » вложенным » A , но это всего лишь объявление. class A не имеет члена типа B .

5. @dxiv Что делать, если у меня есть член B внутри класса A ?

Ответ №1:

Обратите внимание, что для вызова члена с указателем на функцию A вам нужен объект типа A для его вызова. В приведенном ниже примере ссылка на A объект была передана в качестве аргумента B::doStuff .

 #include <iostream>

class A
{
public:
    void (*f)(int);
    A(void (*f)(int)) : f(f) { }

    class B {
    public:
       void (*A::*foo)(int) = amp;A::f;

       void doStuff(A amp;a) {
          (a.*foo)(10);
       } 
    };
};

void testFunction(int a) {
      std::cout << "inside testFunction(" << a << ")" << std::endl;
}

int main()
{
  A a(testFunction);

  A::B b;
  b.doStuff(a);
}
  

Пример вывода: inside testFunction(10) .

Комментарии:

1. Спасибо! К сожалению, я не могу использовать этот подход при передаче объекта A doStuff() . Необходимость создания объекта B, а затем передачи A в качестве аргумента, была бы слишком запутанной для моей ситуации.

2. @LennyWhite Вам не нужно передавать ссылку на объект doStuff в качестве аргумента, вам просто нужно каким-то образом сделать его доступным. Вы хотите вызвать функцию через указатель, хранящийся в A , поэтому A для этого вам нужен экземпляр. В противном случае нет смысла создавать A::f элемент A для начала.

3. Я не определяю. В этом случае, я думаю, мне нужно искать другое решение для того, что я реализовал, где я мог бы передать функцию непосредственно B. Вместо того, чтобы обращаться к члену A.

4. @LennyWhite Вы знаете, как это сделать, поскольку именно так A и работает (чтобы, например, вы могли вызывать a.f(10); from main вместо этого). Однако трудно сказать, следует ли вам / хотите ли вы это сделать, без гораздо большего контекста.