在我的项目中,我有一个类的层次结构。类型为C_t
的对象包含(动态分配的)A_t
个对象数组和B_t
个对象。
我想从A_t
的方法a_fn()
调用B_t
方法b_fn()
。我可以通过几种方式和几种间接方式来做到这一点。
B
维护一个指向其包含对象C
的指针。然后我使用这个指针直接引用A[]
及其方法。
接下来,我定义了指向A_t
的指针并使用对A[]
的引用初始化它们,并使用这些指针间接调用A[]
的方法。
假设在实际项目中层次结构更深,对象名称具有描述性和长度,这种风格变得冗长而复杂的陈述。
我想维护一个指向A[]
方法a_fn()
的指针数组,并使用这些数组成员来调用这些方法。即,如何制作打印x = 46
和x = 47
的(注释掉的)语句?
#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;
}
该程序的输出:
x = 10
x = 11
x = 22
x = 23
x = 34
x = 35
更新:在实际项目中,还有另一级别的层次结构,因此A_t
包含AA_t
和B_t
包含BB_t
个对象指针。因此,方法调用将如下所示:
((*p_A)[0]->AA->*(pa_fn[0]))(34);
并给出了长名称:
((*p_A_object)[0]->AA_sub_object->*(pa_method_fn[0]))(34);
很容易看出这会变得多久而难以阅读。
答案 0 :(得分:2)
正如托比所指出的那样,你不能用普通的指针来做,但可以用 功能+结合:
std::function<void(int)> f_fn = std::bind(&A_t::a_fn, p_A[0]) ;
答案 1 :(得分:1)
为了完成这项工作,你需要一个A_t实例来调用它的一个函数,而不仅仅是一个函数指针。例如。像这样:
#include <iostream>
struct foo { void bar(int x) {std::cout << "moo " << x << std::endl; } };
typedef void (foo::*p_fn_t)(int);
void test(foo f,p_fn_t fn){ (f.*fn)(3); }
int main() {
foo f;
p_fn_t fn = &foo::bar;
test(f,fn);
}
语法很容易出错。通过成员函数指针调用函数是.*
或->*
。
PS:看起来你的例子中的A_t
函数也可以是静态的,这可以解释为什么你没有意识到你需要一个实例。在这种情况下,您可能会考虑简单地使用自由函数而不是将它们放入结构中。 (实际上我不知道如何通过成员函数指针调用静态函数)