如何获取成员函数的函数指针?解决类循环依赖问题
问题根源与解决方案
你的推测完全正确,问题核心就是Foo1和Foo2的循环依赖,同时Foo3的代码也存在语法错误,下面分点说明解决方法:
1. 解决循环依赖:使用前向声明
循环包含(foo1.h包含foo2.h,foo2.h又包含foo1.h)会让预处理器陷入死循环,且Foo1定义时Foo2还未被声明,导致无法识别void (Foo2::*fp)(const double)这个成员函数指针类型。
修正foo1.h,用前向声明替代直接包含foo2.h:
// foo1.h class Foo2; // 前向声明Foo2类,告知编译器这是一个类类型 struct Foo1{ int a1; double b1; void (Foo2::*fp)(const double); // 现在编译器可以识别Foo2类型 };
前向声明的作用是告诉编译器"Foo2是一个类",对于成员函数指针这种只需要知道类存在的场景,完全不需要类的完整定义,刚好适配你的需求。
2. 修正Foo2的头文件
Foo2中包含了Foo1的实例,因此必须包含foo1.h才能获取Foo1的完整定义,修正后的foo2.h还需要补充iostream头文件(因为用到了cout):
// foo2.h #include "foo1.h" #include <iostream> class Foo2{ public: void print_foo2(const double p){ std::cout << "From Foo2: " << p << std::endl; } Foo1 foo1; };
3. 修正Foo3的语法错误
类定义内部不能直接执行赋值语句(除非是静态成员的常量初始化),必须把成员变量的赋值放在构造函数中。修正后的foo3.h如下:
// foo3.h #include "foo2.h" class Foo3 : public Foo2{ private: Foo1 foo1; public: Foo3() { // 在构造函数中给成员函数指针赋值 foo1.fp = &Foo2::print_foo2; } };
额外说明
如果后续需要调用Foo1中fp指向的成员函数,你需要确保调用时Foo2的完整定义已经可见(比如在.cpp文件中包含foo2.h),因为调用成员函数需要知道类的完整结构。
内容的提问来源于stack exchange,提问作者BHOS
相关产品推荐
相关产品推荐

