【发布时间】:2019-06-10 18:05:56
【问题描述】:
我将指向成员函数的指针列表存储在一个数组中。我想索引到数组并执行适当的函数。将有许多数组列出来自不同类的函数(都从 Base 派生),因此在编译时该类是未知的。
我的方案有效,但我对不得不在一个地方使用 void 指针并不完全满意,但我似乎无法避免它。
根据 C++11 标准,我在 Base 和 Derived 成员函数指针之间的转换是否合法(它与 g++ 一起使用)。我将不胜感激语言律师的建议!
下面是我的代码的精简但可运行的版本。
#include <iostream>
using std::cout;
//*************************************
class Base {
public:
typedef int (Base::*BaseThunk)();
virtual int execute(BaseThunk x) {return 0;}
};
//*************************************
class Derived : public Base {
public:
typedef int (Derived::*DerivedThunk)();
int execute(BaseThunk step) {
return (this->*step)(); //Is this OK ? step is really a DerivedThunk.
}
int f1() { cout<<"1\n";return 1;}
int f2() { cout<<"2\n";return 2;}
int f3() { cout<<"3\n";return 3;}
static DerivedThunk steps[];
};
//Here is an array of pointers to member functions of the Derived class.
Derived::DerivedThunk Derived::steps[] = {&Derived::f1, &Derived::f2, &Derived::f3};
//*************************************
class Intermediate : public Base {
public:
void f(void *x) { //I am worried about using void pointer here !
BaseThunk *seq = reinterpret_cast<BaseThunk *>(x);
Derived d;
d.execute(seq[2]);
}
};
//*************************************
int main() {
Intermediate b;
b.f(&Derived::steps);
}
【问题讨论】:
-
请注意,函数指针、成员指针和成员函数指针不保证与
void*兼容。它们可能更大,并且转换为void*并不能保证返回原始值。将函数指针转换为对象指针是conditionally supported,并非所有实现都允许这样做。 -
函数 f 正在接收一个指向 DerivedThunk::* 数组的指针(我认为它是一个普通的数据指针),放入一个 void* 中。然后它将 void* 重新解释为 BaseThunk* 以允许对其进行索引。我认为指向指针部分的数组是合法的,但隐含地假定 BaseThunk 和 DerivedThunk 的大小相同。不太确定这是否总是正确的。
-
您可以在此处使用
static_cast(这有助于避免混淆对象指针与指向成员的指针)。不过,这并不能回答您的问题,因为正如您所说,void*仍然参与其中。
标签: c++ inheritance language-lawyer member-function-pointers