In my project I have an hierarchy of classes. An object of type C_t contains (dynamically allocated) array of A_t objects and a B_t object.
I want to invoke an A_t method a_fn() from a B_t's method b_fn(). I can do that in several ways, and several levels of indirection.
B maintains a pointer to its containing object C. Then I use this pointer to directly refer to A[] and its method.
Next, I defined pointers to A_t and initialized them with the references to A[]s, and use these pointers to indirectly invoke A[]'s method.
Assume that in the actual project the hierarchy is deeper and that the object names are descriptive and long, this style becomes long and convoluted statements.
I want to maintain an array of pointers to A[]'s method a_fn() and use these array members to invoke the methods. I.e., how to make the (commented out) statements that would print x = 46 and x = 47 work?
#include <iostream>
using namespace std;
struct A_t;
struct B_t;
struct C_t;
// Top level class
struct C_t {
A_t *A[2];
B_t *B;
C_t();
};
struct A_t {
void a_fn(int x) { cout << "x = " << x << endl; };
};
// Define func-ptr to A_t's method
typedef void (A_t::*p_fn_t)(int);
struct B_t {
C_t* p_C; // ptr to containing object
A_t** p_A[2]; // array of ptrs-to-array-of-As
p_fn_t p_fn; // ptr to A_t's method
p_fn_t pa_fn[2]; // array of ptr to A_t's method
void b_fn() {
p_C->A[0]->a_fn(10); // Cptr-direct
(p_C->A[0]->*p_fn)(11); // Cptr-indirect
(*p_A)[1]->a_fn(22); // Aptr-direct
((*p_A)[1]->*p_fn)(23); // Aptr-indirect
((*p_A)[0]->*(pa_fn[0]))(34); // Aptr-fptr-indirect
((*p_A)[1]->*(pa_fn[1]))(35); // Aptr-fptr-indirect
//pa_fn[0](46); // <<-- HOW TO DO THIS???
//pa_fn[1](47); // <<-- HOW TO DO THIS???
};
B_t(C_t *C) : p_C(C) {
p_fn = &A_t::a_fn; // init fptr-to-A's-method
p_A[0] = &(p_C->A[0]); // init ptr-to-A[0]
p_A[1] = &(p_C->A[1]); // init ptr-to-A[1]
// The following assignments need to change in order to get
// what I am looking for. Something along the line of
// pa_fn[0] = &(A[0]->(A_t::a_fn));
pa_fn[0] = &A_t::a_fn; // init fptr-to-A's-method
pa_fn[1] = &A_t::a_fn; // init fptr-to-A's-method
};
};
C_t::C_t() {
// Instantiate As and B and init B with C's own ptr
A[0] = new A_t;
A[1] = new A_t;
B = new B_t(this);
};
int main(int argc, char *argv[])
{
C_t C;
C.B->b_fn(); // Invoke B's method
return 0;
}
This program's output:
x = 10
x = 11
x = 22
x = 23
x = 34
x = 35
Update: In the actual project there is another level of hierarchy, so A_t contains AA_t and B_t contains BB_t object pointers. So, the method invocation will look like:
((*p_A)[0]->AA->*(pa_fn[0]))(34);
and given long names:
((*p_A_object)[0]->AA_sub_object->*(pa_method_fn[0]))(34);
It is easy to see how this can become long and hard to read.
A_tto call one of its functions, not only a function pointer