在类A中实例化类B并传递A的成员方法至B构造函数遇编译错误求解
问题:类成员函数作为参数传递给另一个类构造函数的编译错误
问题代码
#include <iostream> using namespace std; class B { public: B(void (*fp)(void)) { fp(); } private: }; class A { public: void printHelloWorld() { cout << "Hello World!" << endl; } private: B ObjB{printHelloWorld}; }; int main() { cout << "!!** Program Start **!!" << endl; A ObjA; cout << "!!** Program End **!!" << endl; return 0; }
编译错误
main.cpp:21:27: error: could not convert ‘{((A*)this)->A::printHelloWorld}’ from ‘’ to ‘B’ 21 | B ObjB{printHelloWorld}; | ^ | | | <brace-enclosed initializer list>
问题原因
类的非静态成员函数无法直接赋值给普通的void (*)(void)函数指针。因为非静态成员函数隐含了一个指向类对象的this指针作为第一个参数,它的实际签名是void (A::*)(void),和普通无参函数指针类型不匹配。而静态成员函数没有this指针,所以可以直接匹配普通函数指针。
解决方案
方案1:使用静态成员函数
将printHelloWorld声明为静态成员函数,消除this指针的影响,使其类型匹配普通函数指针:
#include <iostream> using namespace std; class B { public: B(void (*fp)(void)) { fp(); } private: }; class A { public: static void printHelloWorld() // 改为静态函数 { cout << "Hello World!" << endl; } private: B ObjB{printHelloWorld}; }; int main() { cout << "!!** Program Start **!!" << endl; A ObjA; cout << "!!** Program End **!!" << endl; return 0; }
方案2:用std::function和std::bind绑定this指针
修改B的构造函数接受std::function<void()>类型,通过std::bind将当前对象的this指针和成员函数绑定为可调用对象:
#include <iostream> #include <functional> // 引入头文件 using namespace std; class B { public: B(function<void()> func) // 改用std::function作为参数类型 { func(); } private: }; class A { public: void printHelloWorld() { cout << "Hello World!" << endl; } private: // 绑定当前对象的this指针与成员函数 B ObjB{bind(&A::printHelloWorld, this)}; }; int main() { cout << "!!** Program Start **!!" << endl; A ObjA; cout << "!!** Program End **!!" << endl; return 0; }
方案3:使用lambda表达式(C++11及以上)
利用lambda捕获this指针,生成可直接调用的匿名函数传递给B的构造函数:
#include <iostream> #include <functional> using namespace std; class B { public: B(function<void()> func) { func(); } private: }; class A { public: void printHelloWorld() { cout << "Hello World!" << endl; } private: // lambda捕获this,调用成员函数 B ObjB{[this](){ this->printHelloWorld(); }}; }; int main() { cout << "!!** Program Start **!!" << endl; A ObjA; cout << "!!** Program End **!!" << endl; return 0; }
方案4:修改B的构造函数接受成员函数指针和对象指针
让B的构造函数同时接收A类的成员函数指针和对象指针,通过对象指针调用成员函数:
#include <iostream> using namespace std; // 提前声明A类 class A; class B { public: // 接受A的成员函数指针和对象指针 B(void (A::*fp)(void), A* obj) { (obj->*fp)(); // 通过对象指针调用成员函数 } private: }; class A { public: void printHelloWorld() { cout << "Hello World!" << endl; } private: // 传递成员函数指针和当前对象的this指针 B ObjB{&A::printHelloWorld, this}; }; int main() { cout << "!!** Program Start **!!" << endl; A ObjA; cout << "!!** Program End **!!" << endl; return 0; }
内容的提问来源于stack exchange,提问作者Dheeraj Singhal
相关产品推荐
相关产品推荐

