gpt4 book ai didi

c++ - 向下转换指向成员函数的指针。这是合法的用法吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:14:08 25 4
gpt4 key购买 nike

我将指向成员函数的指针列表存储在一个数组中。我想索引到数组中并执行适当的函数。将有许多数组列出来自不同类(全部派生自 Base)的函数,因此在编译时不知道该类。

我的方案有效,但我对不得不在一个地方使用 void 指针并不完全满意,但我似乎无法避免它。

根据 C++11 标准(它使用 g++),我在 Base 和 Derived 成员函数指针之间的转换是否合法。我将不胜感激语言律师的建议!

下面是我的代码的一个精简但可运行的版本。

#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* 的担忧是有根据的:这是未定义的行为 因为(在 Intermediate::f 中)您正在执行指针对与数组类型不匹配的指针进行算术运算并通读。

好消息是有一个简单的解决方法:因为数组的目的是调用派生类函数,只给定一个 Base& 和一个 BaseThunk ,您可以存储该类型:

Base::BaseThunk Derived::steps[]=
{static_cast<BaseThunk>(&Derived::f1),
…};

static_cast 有点冗长,但只要您使用生成的 BaseThunk 对象和类型为 或派生自 Derived。您甚至不必先获得 Derived*:

int Base::execute(BaseThunk x)  // no need to be virtual
{return (this->*x)();}

关于c++ - 向下转换指向成员函数的指针。这是合法的用法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56531398/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com