如何让类获取未知类的成员函数指针?std::bind致运行崩溃
解决类获取未知类成员函数指针的问题(修复你的崩溃)
首先,你的思路其实完全没问题——用std::function和std::bind包装未知类的成员函数是非常合适的方案,你的代码崩溃大概率是因为缺失必要的头文件或者命名空间的细节遗漏,而非std::bind的用法错误。
我们先把你的代码补全并修复:
#include <iostream> #include <functional> // 必须包含这个头文件,否则std::function和std::bind无法正常工作 using namespace std; // 也可以全程用std::前缀,这里为简化代码使用using class Baz { public: Baz(function<void()> requiredFunc) : mFuncPtr(requiredFunc) {} void doSomethingWithPtr() { mFuncPtr(); } private: function<void()> mFuncPtr; }; class Foo { public: void someFunc() { cout << "Hello World"; } }; int main() { Foo* foo = new Foo(); auto funcPtr = std::bind(&Foo::someFunc, foo); Baz* baz = new Baz(funcPtr); baz->doSomethingWithPtr(); // 现在应该正常输出Hello World了 // 别忘了手动释放内存,避免内存泄漏 delete foo; delete baz; return 0; }
为什么你的代码会崩溃?
最常见的原因是没有包含<functional>头文件——虽然部分编译器可能因为间接依赖让代码编译通过,但std::function和std::bind的完整实现完全依赖这个头文件,缺失会导致运行时触发未定义行为(比如崩溃)。
另外,如果你没写using namespace std;,那cout需要写成std::cout,不过你提到代码能编译通过,所以更大概率是<functional>的缺失问题。
扩展:更安全的写法(避免裸指针)
为了减少手动管理内存的麻烦,推荐使用智能指针来优化代码:
#include <iostream> #include <functional> #include <memory> using namespace std; class Baz { public: Baz(function<void()> requiredFunc) : mFuncPtr(move(requiredFunc)) {} void doSomethingWithPtr() { mFuncPtr(); } private: function<void()> mFuncPtr; }; class Foo { public: void someFunc() { cout << "Hello World\n"; } }; int main() { auto foo = make_shared<Foo>(); auto funcPtr = bind(&Foo::someFunc, foo); auto baz = make_unique<Baz>(funcPtr); baz->doSomethingWithPtr(); // 不需要手动释放内存,智能指针会自动处理生命周期 return 0; }
原理说明
std::bind会把成员函数指针和对象(或对象指针/智能指针)绑定在一起,生成一个可调用的函数对象,这个对象可以被std::function<void()>完美包装。std::function是通用的函数包装器,它可以存储任何可调用对象(普通函数、lambda、bind生成的对象等),刚好解决你“获取未知类成员函数指针”的需求——你不需要知道函数属于哪个类,只需要匹配void()的签名即可。
内容的提问来源于stack exchange,提问作者Ranje25
相关产品推荐
相关产品推荐

