C++中如何将类成员函数指针传递给其他类方法?
Hey there! I totally get that wading through generic posts about member function pointers can leave you stuck when your specific class setup doesn’t line up. Let’s walk through practical, tailored solutions for passing your Eom::get_pos and Eom::set_pos methods to other classes like Rk4, using your three-class structure as a guide.
1. Basic Member Function Pointers (No Extra Libraries)
Member function pointers require an instance of the class to work—since they’re tied to the object’s state. Here’s how you can pass them directly between your classes:
First, your Eom class (for context):
class Eom { public: void set_pos(double x) { // Your position-setting logic here } double get_pos() const { // Your position-getting logic here return 0.0; // Placeholder } };
Update your Rk4 class to accept member function pointers along with an Eom instance:
class Rk4 { public: // For non-const member functions like set_pos void execute_set(Eom& eom_instance, void (Eom::*set_method)(double)) { // Syntax to call the member function on the instance (eom_instance.*set_method)(15.5); // Example value to pass } // For const member functions like get_pos void execute_get(const Eom& eom_instance, double (Eom::*get_method)() const) { double current_pos = (eom_instance.*get_method)(); // Use current_pos in your Rk4 logic here } };
Then in your Manage class, tie it all together:
class Manage { public: void run_simulation() { Eom my_eom; Rk4 my_rk4; // Pass set_pos and the Eom instance to Rk4 my_rk4.execute_set(my_eom, &Eom::set_pos); // Pass get_pos and the Eom instance to Rk4 my_rk4.execute_get(my_eom, &Eom::get_pos); } };
2. Using std::function and std::bind (More Flexible)
If the raw member function pointer syntax feels clunky, std::function lets you wrap the function and its associated object into a single callable. std::bind helps tie the Eom instance to the member function:
#include <functional> // Required for std::function and std::bind class Rk4 { public: // Now we accept generic callables instead of raw pointers void execute_set(std::function<void(double)> set_func) { set_func(15.5); // Call directly, no instance needed } void execute_get(std::function<double()> get_func) { double current_pos = get_func(); // Use current_pos in your Rk4 logic here } }; class Manage { public: void run_simulation() { Eom my_eom; Rk4 my_rk4; // Bind set_pos to my_eom, leaving the parameter open auto bound_set = std::bind(&Eom::set_pos, &my_eom, std::placeholders::_1); my_rk4.execute_set(bound_set); // Bind get_pos to my_eom (no parameters needed) auto bound_get = std::bind(&Eom::get_pos, &my_eom); my_rk4.execute_get(bound_get); } };
3. Lambda Expressions (C++11+, Cleanest Option)
Lambdas let you capture the Eom instance directly, making the code more readable and avoiding the need for std::bind. This is my go-to for most cases:
#include <functional> // Required for std::function class Rk4 { public: void execute_set(std::function<void(double)> set_func) { set_func(15.5); } void execute_get(std::function<double()> get_func) { double current_pos = get_func(); // Use current_pos in your Rk4 logic here } }; class Manage { public: void run_simulation() { Eom my_eom; Rk4 my_rk4; // Capture my_eom by reference and wrap set_pos my_rk4.execute_set([&my_eom](double x) { my_eom.set_pos(x); }); // Capture my_eom by reference and wrap get_pos my_rk4.execute_get([&my_eom]() { return my_eom.get_pos(); }); } };
If your specific use case has unique constraints—like needing Rk4 to store these functions long-term, or handling thread safety—feel free to share those details, and we can tweak these solutions further!
内容的提问来源于stack exchange,提问作者ndlawrence

