向量的函数指针

Mat*_*teo 4 c++ arrays function-pointers vector

我正在尝试编写Gameboy模拟器代码,我想使用函数指针向量来调用正确的函数,而不是执行long switch语句.

例如,如果程序计数器指向0x00(在内存中),则向量的第一个元素是NOP,因此调用void NOP(); 但我无法想象如何调用这些函数.

Z80.h

#include <vector>
using namespace std;

class Z80;
typedef void (Z80::*function_t)();

class Z80
{
public:
  vector<function_t> fmap;
...
...
};
Run Code Online (Sandbox Code Playgroud)

Z80.cpp

Z80::Z80()
{
    fmap = { &Z80::NOP, &Z80::LDBCnn, &Z80::LDBCmA};
}

void Z80::emulateCycle() {
    opcode = memory.readByte(r.pc);
    fmap[opcode]();     <---ERROR
    r.pc++;
}

void Z80::NOP() {

}
Run Code Online (Sandbox Code Playgroud)

这是错误:

IntelliSense: expression preceding parentheses of apparent call must have (pointer-to-) function type
Run Code Online (Sandbox Code Playgroud)

Bar*_*rry 5

这个表达式:

fmap[opcode]
Run Code Online (Sandbox Code Playgroud)

为您提供指向成员函数的指针.你不能只是调用它 - 它也需要类实例.但是你实际上是从类方法本身调用它 - 所以this你正在寻找的实例:

(this->*fmap[opcode])();
Run Code Online (Sandbox Code Playgroud)

请注意,如果您想避免使用这一点语法,并且您正在使用C++ 11,则可以将您更改fmap为to to vector std::function<void()>并进行初始化:

fmap = { std::bind(&Z80::NOP, this),    // or [this](){ this->NOP(); }
         std::bind(&Z80::LDBCnn, this), // etc.
         std::bind(&Z80::LDBCmA, this)};
Run Code Online (Sandbox Code Playgroud)

这会让你真正做到:

fmap[opcode]();
Run Code Online (Sandbox Code Playgroud)


Mat*_*son 5

我不完全确定在这种情况下使用函数指针比例如一个大的switch语句要好得多.

但是,您无法调用成员函数的原因是您没有将对象传递给函数.

你需要这个;

(this->*fmap[opcode])();
Run Code Online (Sandbox Code Playgroud)

另一种选择是使用静态/自由函数指针,如下所示:

 void (*function_t)(Z80& self); 
Run Code Online (Sandbox Code Playgroud)

并称之为:

 fmap[opcode](this). 
Run Code Online (Sandbox Code Playgroud)

[或者使用std::functionand std::bind,它覆盖了相当(有意,显然)丑陋的语法]