在C++98中将类内的函数指针成员提供给其他类调用
在C++98中,要将一个类的成员函数指针提供给其他类使用,有几种常见的方法。下面我将介绍几种可行的方案。
方法1:使用静态成员函数作为桥梁
class ClassA {
public:
void memberFunc(int x) {
// 成员函数实现
}
// 静态函数作为桥梁
static void staticBridge(ClassA* obj, int x) {
obj->memberFunc(x);
}
};
class ClassB {
public:
typedef void (*FuncPtr)(ClassA*, int);
void setCallback(FuncPtr ptr, ClassA* obj) {
m_func = ptr;
m_obj = obj;
}
void callCallback(int x) {
if (m_func) {
m_func(m_obj, x);
}
}
private:
FuncPtr m_func;
ClassA* m_obj;
};
// 使用示例
ClassA a;
ClassB b;
b.setCallback(&ClassA::staticBridge, &a);
b.callCallback(42);
方法2:使用成员函数指针
class ClassA {
public:
void memberFunc(int x) {
// 成员函数实现
}
};
class ClassB {
public:
typedef void (ClassA::*MemberFuncPtr)(int);
void setCallback(MemberFuncPtr ptr, ClassA* obj) {
m_func = ptr;
m_obj = obj;
}
void callCallback(int x) {
if (m_func && m_obj) {
(m_obj->*m_func)(x);
}
}
private:
MemberFuncPtr m_func;
ClassA* m_obj;
};
// 使用示例
ClassA a;
ClassB b;
b.setCallback(&ClassA::memberFunc, &a);
b.callCallback(42);
方法3:使用接口类(更面向对象的方式)
class ICallback {
public:
virtual ~ICallback() {}
virtual void callback(int x) = 0;
};
class ClassA : public ICallback {
public:
virtual void callback(int x) {
// 实现回调
}
};
class ClassB {
public:
void setCallback(ICallback* cb) {
m_callback = cb;
}
void callCallback(int x) {
if (m_callback) {
m_callback->callback(x);
}
}
private:
ICallback* m_callback;
};
// 使用示例
ClassA a;
ClassB b;
b.setCallback(&a);
b.callCallback(42);
方法4:使用仿函数(Functor)
class Callback {
public:
virtual ~Callback() {}
virtual void operator()(int x) = 0;
};
class ClassA {
public:
class MyCallback : public Callback {
public:
MyCallback(ClassA* parent) : m_parent(parent) {}
virtual void operator()(int x) {
m_parent->memberFunc(x);
}
private:
ClassA* m_parent;
};
void memberFunc(int x) {
// 成员函数实现
}
};
class ClassB {
public:
void setCallback(Callback* cb) {
m_callback = cb;
}
void callCallback(int x) {
if (m_callback) {
(*m_callback)(x);
}
}
private:
Callback* m_callback;
};
// 使用示例
ClassA a;
ClassB b;
b.setCallback(new ClassA::MyCallback(&a));
b.callCallback(42);
总结
- 静态函数桥梁:简单直接,但需要额外静态函数
- 成员函数指针:直接使用成员函数指针,语法稍复杂
- 接口类:更面向对象,推荐用于复杂场景
- 仿函数:灵活但需要更多代码
在C++98中,接口类方法通常是最推荐的方式,因为它提供了更好的类型安全性和扩展性。如果只需要简单的回调,成员函数指针方法也可以工作得很好。
注意在真实代码中要考虑对象生命周期管理,避免悬空指针等问题。