#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);
frommain
вместо этого). Однако трудно сказать, следует ли вам / хотите ли вы это сделать, без гораздо большего контекста.