调用成员函数指针时指向与对象不兼容的成员类型的指针

问题描述

问题

我有一个在运行时分配的成员函数指针数组。尝试调用它们时出现编译时错误

指向成员类型 'void (Ycpu::)(uint16_t)' {aka 'void (Ycpu::)(short unsigned int)'} 的指针与对象类型 'YcpuInstruction' 不兼容`

我无法理解调用指针的正确语法。

代码和问题详情

我有一个结构体 YcpuInstruction 来存储两个成员函数指针。这些函数指针指向 Ycpu 内的成员函数。我存储了一个 YcpuInstructions 数组,并在初始化期间调用 initialize ,它将这些指针分配给正确的成员函数

成员函数指针和YcpuInstruction:

typedef void (Ycpu::*YcpuOpcode)(uint16_t opcode);
typedef std::string (Ycpu::*Ycpudisassembler)(std::string name,uint16_t operand,uint16_t nextword,uint16_t address,bool show_memory_contents,uint16_t &instruction_size);


struct YcpuInstruction {
    std::string name;

    static YcpuOpcode opcode;
    static Ycpudisassembler disassembler;

    int cycles;
    bool is_nop;

    void initialize(std::string name,YcpuOpcode opcode,Ycpudisassembler disassembler,int cycles,bool is_nop = false)
    {
        this->name = name;
        this->opcode = opcode;
        this->disassembler = disassembler;
        this->cycles = cycles;
        this->is_nop = is_nop;
    }
};

Ycpu

class Ycpu
{
public:
    // YcpuOpcode points to one these functions (many more than these 3,just examples)
    void nop(uint16_t opcode);
    void ADC(uint16_t opcode);
    void ADD(uint16_t opcode);
    ...
    // Ycpudisassembler points to one of these functions (many more than these 2,just examples)
    std::string disassemble_ALU(std::string name,uint16_t &instruction_size);
    std::string disassemble_BRA(std::string name,uint16_t &instruction_size);
    ...
private:
    std::array<YcpuInstruction,256> opcodes;
};

在设置过程中,我像这样初始化操作码:

void Ycpu::initialize_opcodes()
{
    opcodes[0x01].initialize("CMP",&Ycpu::CMP,&Ycpu::disassemble_ALU,0);
    opcodes[0x02].initialize("CMP",0);
    opcodes[0x03].initialize("CMP",0);
    ... // and so on for all instructions 
}

初始化后,我尝试像这样调用成员函数

void Ycpu::run_one_instruction()
{
    ...
    uint16_t word = read_mem_int16(PC,SI_CS); // 0x1-0xff
    YcpuInstruction op = opcodes[word & 0xFFFF];
    (op.*YcpuInstruction::opcode)(word);
    ...
}

然而,这会引发我上面提到的编译器错误

如果我先取消引用 op,如下所示:

(op->*YcpuInstruction::opcode)(word);

我收到此错误

错误:'operator->*' 不匹配(操作数类型是 'YcpuInstruction' 和 'YcpuOpcode' {aka 'void (Ycpu::*)(short unsigned int)'})

如果我将语法更改为:

(op->*opcode)(word);

或:

(op.*opcode)(word)

我收到此错误

错误:'opcode' 未在此范围内声明

调用这些成员函数指针需要使用的具体语法是什么?

解决方法

.* 的左操作数必须引用/->* 的左操作数必须指向成员函数的包含类的对象。右操作数可以是任何给出成员指针值的表达式。

您使用的成员函数的包含类是 YCPU,因此将 YCPUInstruction 作为左操作数是不正确的。我看到您的表达式在 YCPU 的另一个成员函数中,因此假设您想使用 *this 作为调用该函数的 YCPU,您需要 this->*。下面的表达式可以是普通的 .-> 表达式,用于从 YCPUInstruction 获取而不是调用指向成员函数的指针值。由于 .*->* 的优先级很奇怪,因此经常需要并始终建议使用过多的括号。

void YCPU::run_one_instruction()
{
    // ...
    uint16_t word = read_mem_int16(PC,SI_CS); // 0x1-0xff
    YCPUInstruction op = opcodes[word & 0xFFFF];
    (this->*(op.opcode))(word);
    // ...
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...