【发布时间】:2016-03-26 23:17:42
【问题描述】:
我需要用一些 API 注册一个函数指针表。假设 API 如下所示:
void (*FuncPtr)(void*);
void RegisterCallbacks(FuncPtr const (&callbacks)[10], void* context);
由于我正在编写 OOP 代码,因此我在我的类中创建了静态“thunk”方法,这些方法依次调用我的类的对象上的方法。我使用context 指针将指针传递给我的对象。我想在静态初始化时静态分配整个回调指针表。所以我最终得到了这个:
class MyClass
{
public:
static void Thunk (void* context)
{
reinterpret_cast<MyClass*>(context)->Method();
}
void Method ();
//
// More callback thunks and methods...
//
MyClass ()
{
RegisterCallbacks(s_callbackTable, this);
}
private:
static const FuncPtr s_callbackTable[];
}
//
// In the .cpp file:
//
const FuncPtr MyClass::s_callbackTable[] =
{
&MyClass::Thunk,
...
};
这种方法的问题是我需要让MyClass::Thunk公开可见,以便静态初始化可以访问它。
编辑:我错了。显然你不需要公开它。
我宁愿不要。我可以想到两种方法来解决这个问题。
哪种方法更好?
创建私有静态方法,并将回调表设为方法内部的静态变量。这样我也可以使用指向私有方法的指针来初始化它。从构造函数内部调用私有静态方法来获取表。
-
创建一个包含公共静态 thunk 方法的单独类,并使该类成为
MyClass的朋友。在MyClass的标题中前向声明该类,只是为了允许朋友声明。我喜欢这个,因为它还完全对任何外部消费者隐藏了 thunk 方法。不过,我不确定这是否有切实的好处。像这样:
// .h file: class MyClassInternals class MyClass { public: void Method (); private: friend class MyClassInternals; static const FuncPtr s_callbackTable[]; } // .cpp file: class MyClassInternals { public: static void Thunk(void* context) { reinterpret_cast<MyClass*>(context)->Method(); } } const FuncPtr MyClass::s_callbackTable[] = { &MyClassInternals::Thunk, ... };
【问题讨论】:
标签: c++ callback private friend