Прежде чем решить, как это сделать, задайте вопрос: что вы хотите сделать и почему. Потому что, возможно, есть лучшие альтернативы, использующие простые идиомы C ++.
Вариант 1: специализация с полиморфизмом
Вы хотите специализировать некоторые функции вашего коммутатора, поэтому вместо вызова функции auto_switch
Вы бы назвали купол более специализированным?
В этом случае вы не сделаете:
//doesn't work
led_switch = new auto_switch(main_led->turn_on, main_led->turn_off, 3);
, но вместо этого вы будете полагаться на полиморфизм с виртуальными функциями в базовом классе:
class auto_switch {
...
virtual void turn_on();
virtual void turn_off();
...
};
и писать специализированный класс для светодиодов:
class led_witch : public auto_switch {
...
void turn_on() override;
void turn_off() override;
...
};
На самом деле, компилятор будет генерировать некоторые указатели на функции за сценой, но вам не нужно заботиться:
auto_switch s1=new auto_switch(...);
auto_switch s2=new led_switch(...); // no problem !!
s1->turn_on(); // calls auto_switch::turn_on()
s2->turn_on(); // calls led_switch::turn_on() since the real type of s2 is led_switch
Но событие если поведение каждого объекта является динамическим c на основе реального класса объекта, объекты того же класса имеют поведение, которое было предопределено во время компиляции. Если это не так, go до следующего варианта.
Вариант 2: указатель на функцию-член
Функции других объектов можно вызывать только с этим объектом под рукой. Таким образом, наличие указателя на функцию led недостаточно: вам также необходимо знать, к какому индикатору он будет применен.
Вот почему указатели на функции-члены отличаются и несколько ограничены: вы можете вызывать только функции класса вашего указателя на функцию-член. Если полиморфизма достаточно (т. Е. Если производный класс имеет другую реализацию функции, уже предусмотренной в базовом классе), то вам повезло. Если вы хотите использовать функцию, которая существует только в производном классе, а не в базовом классе, она не будет компилироваться.
Вот упрощенная версия auto_swith
: я предоставляю функцию, но также указатель на объект, для которого должна быть вызвана функция:
class auto_switch{
void (led::*action)();
led *ld;
public:
auto_switch(void(led::*a)(), led*l) : action(a), ld(l) {}
void go () { (ld->*action)(); }
};
// usage:
auto_switch s(&led::turn_off, &l1);
s.go();
Онлайн-демонстрация
Вариант 3: функциональный способ (может, это то, что вы ищете?)
Другим вариантом будет использование стандартной функциональной библиотеки для привязки функции-члена и объекта на котором оно должно быть выполнено (а также любые необходимые параметры):
class auto_switch{
std::function<void()> action;
public:
auto_switch(function<void()>a) : action(a) {}
void go () { action(); }
};
Здесь вы можете связать что угодно: любую функцию любого класса:
auto_switch s(bind(&led::turn_off, l1));
s.go();
auto_switch s2(bind(&blinking_led::blink, l2));
s2.go();
Онлайн-демонстрация
Опция 4: шаблон команды
Теперь, если вы хотите выполнить что-то на объекте при включении и выключении коммутатора, но вам нужна полная гибкость, вы можете просто реализовать шаблон команды : это позволяет вам выполнять что-либо на любом объекте. И вам даже не нужен указатель на функцию.