在C语言中,传递函数指针是非常常见的操作。
在C++语言中,使用C语言一致的方法传递全局函数指针,或者传递静态函数指针也很常见。
不过如果遇到想传递非静态成员函数时,可以参考以下示例代码。
cpp
#ifndef _WORKER_HPP_
#define _WORKER_HPP_
#include <iostream>
#include <unistd.h>
#include <functional>
#include <chrono>
#include <iomanip>
#include <sstream>
class Worker {
public:
// 设置回调函数
void registerCallback(std::function<void(int, std::string, long)> cb) {
this->mCallback = cb;
}
void startWork() {
using namespace std::literals;
const std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
const std::time_t t_c = std::chrono::system_clock::to_time_t(now);
int i = 1008;
std::stringstream ss;
ss << std::put_time(std::localtime(&t_c), "%F %T");
std::string s = ss.str();
long l = __cplusplus;
mCallback(i, s, l);
}
private:
std::function<void(int, std::string, long)> mCallback;
};
#endif
参考Manager内的work函数,列出了几种写法。
cpp
#ifndef _MANAGER_HPP_
#define _MANAGER_HPP_
#include <functional>
#include <string>
#include <iostream>
#include "worker.hpp"
class Manager {
public:
Manager(): mI(-1), mS("coco"), mL(-1L) {
}
virtual ~Manager() = default;
public:
void work() {
using namespace std::placeholders;
// 设置回调函数, 使用lambda
worker.registerCallback([this](int&& i, std::string&& s, long&& l) -> void {
this->onMsgCallback(i, s, l);
});
// 设置回调函数,使用bind,搭配mem_fn
auto ptr = std::mem_fn(&Manager::onMsgCallback);
worker.registerCallback(std::bind(ptr, this, _1, _2, _3));
// 不搭配mem_fn
worker.registerCallback(std::bind(&Manager::onMsgCallback, this, _1, _2, _3));
worker.startWork();
}
void print() {
std::cout << __FUNCTION__ << " mI is " << mI << ", mS is " << mS << ", mL is " << mL << std::endl;
}
private:
void onMsgCallback(int i, std::string s, long l) {
std::cout << __FUNCTION__ << " i is " << i << ", s is " << s << ", l is " << l << std::endl;
this->mI = i;
this->mS = s;
this->mL = l;
}
private:
int mI;
std::string mS;
long mL;
Worker worker;
};
#endif
main示例:
cpp
int main()
{
// 演示将非静态成员函数设置为回调函数
{
Manager manager;
manager.print();
manager.work();
manager.print();
}
return 0;
}
输出参考:
print mI is -1, mS is coco, mL is -1
onMsgCallback i is 1009, s is 2023-11-18 20:22:34, l is 201402
print mI is 1009, mS is 2023-11-18 20:22:34, mL is 201402