微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

问题

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

指向成员类型 '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);
    // ...
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。