I am using Arduino C++11
I want to create and execute a dynamically function pointer list from different instantiated class members. A function holding the dynamic list of funtion pointerns is called in the main program. I have tried several solutions, but I am stuck.
I hope the the framework below is sufficient documentation. If not please let me know.
class base {
// base class for holding global static functions. Shall not be instatited.
// if necessary, change class to namespace or struct.
private:
friend class class_inp;
friend class class_out;
static void base_add_funtion_pointer_from_instatiated_class_member
(/* function pointer upddate_event_control() */) {
// what do do?
}
public:
static void execute_dynamic_list_of_instatiated_function_pointers() {
// how to do it?
}
};
Two class with identical functions to call
class class_inp : public base {
public:
class_inp (bool eventSwitch) {
base_add_funtion_pointer_from_instatiated_class_member
(/* function pointer from upddate_event_control() */);
}
void upddate_event_control();
};
class class_out : public base {
public:
class_out (/* arguments*/) {
base_add_funtion_pointer_from_instatiated_class_member
(/* function pointer from upddate_event_control() */);
}
void upddate_event_control();
};
Main program
class_inp inp;
class_out out;
// Arduino main
void loop() {
base::execute_dynamic_list_of_instatiated_function_pointers();
delay(1); // waith 1 millisecond
}
you want to avoid dynamic allocations on embedded devices, but you can have linked lists. basically each object will contain a next
pointer, and will register itself in the constructor.
class base {
// base class for holding global static functions. Shall not be instatited.
// if necessary, change class to namespace or struct.
private:
friend class class_inp;
friend class class_out;
static void base_add_funtion_pointer_from_instatiated_class_member
(base* object) {
if (begin == nullptr)
{
begin = object;
}
if (end != nullptr)
{
end->next = object;
}
end = object;
}
static base* begin;
static base* end;
base* next = nullptr;
protected:
virtual void update_event_control() = 0;
public:
base(const base&) = delete;
base& operator=(const base&) = delete;
base() {}
static void execute_dynamic_list_of_instatiated_function_pointers() {
base* object = begin;
while (object != nullptr)
{
object->update_event_control();
object = object->next;
}
}
};
// make sure those two are in a .cpp file
base* base::begin = nullptr;
base* base::end = nullptr;
class class_inp : public base {
public:
class_inp (bool eventSwitch = false) {
base_add_funtion_pointer_from_instatiated_class_member(this);
}
void update_event_control() override {
std::cout << "inp\n";
}
};
improvements for future if needed: unregister the object in the destructor.
if only 1 member function is ever needed, you can remove virtual
and store a function pointer, this removes a few cycles (3 instructions per call), this is not needed for a computer but may make a difference on a microcontroller.
class base {
// base class for holding global static functions. Shall not be instatited.
// if necessary, change class to namespace or struct.
private:
friend class class_inp;
friend class class_out;
static void base_add_funtion_pointer_from_instatiated_class_member
(base* object) {
if (begin == nullptr)
{
begin = object;
}
if (end != nullptr)
{
end->next = object;
}
end = object;
}
static base* begin;
static base* end;
base* next = nullptr;
using func_type = void (*)(base*);
func_type func = nullptr;
public:
base(const base&) = delete;
base& operator=(const base&) = delete;
base(func_type f) : func{f} {}
static void execute_dynamic_list_of_instatiated_function_pointers() {
base* object = begin;
while (object != nullptr)
{
object->func(object);
object = object->next;
}
}
};
// make sure those two are in a .cpp file
base* base::begin = nullptr;
base* base::end = nullptr;
class class_inp : public base {
public:
class_inp (bool eventSwitch = false)
:base{[](base* p) { static_cast<class_inp*>(p)->update_event_control(); }}
{
base_add_funtion_pointer_from_instatiated_class_member(this);
}
void update_event_control() {
std::cout << "inp\n";
}
};