C++中的结构错误

Posted

技术标签:

【中文标题】C++中的结构错误【英文标题】:Error with Struct in C++ 【发布时间】:2012-02-25 05:31:18 【问题描述】:

我在 C++ (visual studio) 中尝试执行此操作时遇到结构问题:

memoria.cpp

  struct readMem 
    UINT32 startAdress;
    UINT32 endAdress;
    UINT8(*memoryHandler) (UINT32);
    void *pUserData;
;

struct writeMem 
    UINT32 startAdress;
    UINT32 endAdress;
    void (*memoryHandler) (UINT32, UINT8);
    void *pUserData;
;



 void memoria::writeRAMBankEnable(UINT32 a, UINT8 b) 


void memoria::writeROMBankSelect(UINT32 a, UINT8 b) 


void memoria::writeRAMROMModeSelect(UINT32 a, UINT8 b) 


void memoria::writeVRAM(UINT32 a, UINT8 b) 


void memoria::writeSRAM(UINT32 a, UINT8 b) 


void memoria::writeRAM(UINT32 a, UINT8 b) 


void memoria::writeERAM(UINT32 a, UINT8 b) 


void memoria::writeSprite(UINT32 a, UINT8 b) 


void memoria::writeIOM(UINT32 a, UINT8 b) 


void memoria::writeHRAM(UINT32 a, UINT8 b) 



struct writeMem implWriteMem[] = 
     0x0000, 0x1FFF, writeRAMBankEnable, NULL,
     0x4000, 0x5FFF, writeROMBankSelect, NULL,
     0x6000, 0x7FFF, writeRAMROMModeSelect, NULL,
     0x8000, 0x9FFF, writeVRAM, NULL,
     0xA000, 0xBFFF, writeSRAM, NULL,
     0xC000, 0xDFFF, writeRAM, NULL,
     0xE000, 0xFDFF, writeERAM, NULL,
     0xFE00, 0xFE9F, writeSprite, NULL,
     0xFF00, 0xFF7F, writeIOM, NULL,
     0xFF80, 0xFFFF, writeHRAM, NULL,
     (UINT32) - 1, (UINT32) - 1, NULL, NULL
;

    memoria.h    

        #pragma once

#include <stdlib.h>
#include <stdio.h>
#include "defs.h"

ref class memoria

public:
    memoria(void);

private:
    FILE *file;
    UINT8 *mem;
public:

    void writeRAMBankEnable(UINT32, UINT8);

    void writeROMBankSelect(UINT32, UINT8);

    void writeRAMROMModeSelect(UINT32, UINT8);

    void writeVRAM(UINT32, UINT8);

    void writeSRAM(UINT32, UINT8);

    void writeRAM(UINT32, UINT8);

    void writeERAM(UINT32, UINT8);

    void writeSprite(UINT32, UINT8);

    void writeIOM(UINT32, UINT8);

    void writeHRAM(UINT32, UINT8);

    UINT8 readRAMBankEnable(UINT32);

    UINT8 readROMBankSelect(UINT32);

    UINT8 readRAMROMModeSelect(UINT32);

    UINT8 readVRAM(UINT32);

    UINT8 readSRAM(UINT32);

    UINT8 readRAM(UINT32);

    UINT8 readERAM(UINT32);

    UINT8 readSprite(UINT32);

    UINT8 readIOM(UINT32);

    UINT8 readHRAM(UINT32);


    void Meminitialize();
    void MemcleanUp();

    void writeByte(UINT32, UINT8);
    UINT8 readByte(UINT32);

    void writeWord(UINT32, UINT16);
    UINT16 readWord(UINT32);
;

Visual Studio C++ 给我这个错误:

1>memoria.cpp(75):错误 C2065:'writeRAMBankEnable':未声明的标识符

1>memoria.cpp(76):错误 C2065:'writeROMBankSelect':未声明的标识符

1>memoria.cpp(77):错误 C2065:'writeRAMROMModeSelect':未声明的标识符

1>memoria.cpp(78): error C2065: 'writeVRAM' : undeclared identifier

1>memoria.cpp(79): error C2065: 'writeSRAM' : undeclared identifier

1>memoria.cpp(80): error C2065: 'writeRAM' : undeclared identifier

1>memoria.cpp(81): error C2065: 'writeERAM' : undeclared identifier

1>memoria.cpp(82): error C2065: 'writeSprite' : undeclared identifier

1>memoria.cpp(83): error C2065: 'writeIOM' : undeclared identifier

1>memoria.cpp(84): error C2065: 'writeHRAM' : undeclared identifier

1>memoria.cpp(169):错误 C2065:'implReadMem':未声明的标识符

1>memoria.cpp(179):错误 C2065:“implReadMem”:未声明的标识符

为了记录,我已经在 memoria.h 中声明了所有函数,当然,除了结构和 implWriteMem[]。 无论如何,我该如何解决?

附:它在纯 C 中运行良好。

谢谢!

【问题讨论】:

提供标题,无法判断发生了什么 纯 C 没有命名空间。这是如何工作的? 您是否要创建一个 DIY 成员函数?天哪!!!! @Anycorn:不仅仅是成员函数,还有多态(虚拟)成员函数。所以虚函数和类继承似乎是更好的解决方案。 【参考方案1】:
 0x0000, 0x1FFF, writeRAMBankEnable, NULL,

你是不是想说

 0x0000, 0x1FFF, &memoria::writeRAMBankEnable, NULL,

在引用成员时必须包含类名,但在类中除外。并且在创建指向成员函数的指针时,总是需要类名。

最好的解决方案是使用语言内置的多态特性:

ref struct MemoryRegion abstract

     virtual uint8_t Read( uint32_t address ) = 0;
     virtual void Write( uint32_t address, uint8_t value ) = 0;
     const uint32_t start_address, end_address;
protected:
     MemoryRegion( uint32_t start, uint32_t end ) : start_address(start), end_address(end) 
;

ref struct SRAM : MemoryRegion

     SRAM( uint32_t start, uint32_t end ) : MemoryRegion(start, end) 
     virtual uint8_t Read(uint32_t address);
     virtual void Write(uint32_t address, uint8_t value);
;

ref struct RAM : MemoryRegion

     RAM( uint32_t start, uint32_t end ) : MemoryRegion(start, end) 
     virtual uint8_t Read(uint32_t address);
     virtual void Write(uint32_t address, uint8_t value);
;

ref struct VRAM : MemoryRegion

     VRAM( uint32_t start, uint32_t end ) : MemoryRegion(start, end) 
     virtual uint8_t Read(uint32_t address);
     virtual void Write(uint32_t address, uint8_t value);
;

等等。然后你可以为基类型制作一个句柄数组,并填写各种特定于行为的类:

array<MemoryRegion^>^ memories = gcnew array<MemoryRegion^>(10);
memories[0] = gcnew SRAM(0xA000, 0xBFFF);
// ...

【讨论】:

希望这些成员函数也是静态的。 @Anycorn:是的,该结构确实似乎存储了一个普通函数指针,而不是指向非静态成员类型的指针。 我认为 OP 使用了一个 hack 来使用 C 重新创建一些 OOP。鉴于成员函数已经存在于 lang 中,他可能不应该在 C++ 中这样做。 @BenVoigt 我试过了,但现在我得到了这个错误:1>memoria.cpp(73): error C2440: 'initializing' : cannot convert from 'void (__clrcall memoria::* )(unsigned int,unsigned char)' 到 'void (__clrcall *)(unsigned int,unsigned char)' 没有可以进行这种转换的上下文 @LeonardoFerrari:这就是 Anycom 所说的。非静态成员函数与普通函数不兼容。为什么不告诉我们您正在使用 C++/CLI 并编译为 .NET?

以上是关于C++中的结构错误的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++ 中的向量结构中使用结构向量?

在 C++ 中为结构读取二进制文件的运行时错误

c++中的时间函数引用

C++ 中的指针错误

C++ - 使用带有结构的 GTest 值参数化测试会导致 valgrind 错误

C++:动态共享库中的虚函数产生段错误