这是我第一次在stackoverflow上发帖,希望这能遵守所有礼节!
我试图使用SDL 1.x扩展库在C++中创建和实现按钮类,以与使用有限状态机的个人项目一起使用。我有一个带有虚函数的基类,即“按钮”,从Button派生的类,“MenuButton”和试图创建MenuButton的“Title”状态。
我使用的是Microsoft Visual Studio 2012,Intellisense说我的代码正确。但是,当我尝试编译时,出现以下两个错误:

我花了几个小时试图自己解决问题。我搜索过google,也一直在搜索stackoverflow,但是尽管我看到并阅读了许多其他类似问题的文章,但似乎没有一个是我遇到的同样的问题。
基于其他人发布的其他类似问题以及他们接受的答案,我已经在搜索:#include循环问题,确保类声明具有最终的;并确保包括了所有#include(据我所知) 。
下面是代码段,如果有人可以告诉我如何解决这个问题,我将感谢您的智慧和帮助。
谢谢
Button.h(基类)

#ifndef BUTTON_H
#define BUTTON_H

#include "SDL.h"
#include "SDL_image.h"
#include "SDL_ttf.h"
#include "Functions.h"
#include "Globals.h"
#include "Constants.h"
#include <string>

using namespace std;

class Button
{
public:
    virtual void handleEvents() = 0;

    virtual void render() = 0;

    //virtual ~Button(void){};
protected:
    //Our enumerated type
    const enum mouseStates {CLIP_MOUSEOUT, CLIP_MOUSEOVER, CLIP_MOUSEDOWN, CLIP_MOUSEUP};

    //Our rect to hold the offsets and size of the button
    SDL_Rect button;

    //Array of rects to hold the dimensions of each clip from the sprit sheet
    SDL_Rect clips[4];

    //Holds the location and size of the clip to show from sprite sheet
    SDL_Rect *clip;

    //The sprite sheet surface from which we clip the button images
    SDL_Surface *buttonSpriteSheet;

    //The surface for our button text
    SDL_Surface *buttonSurfaceText;

    //The text for our button
    string buttonText;

    //The state the button will lead to when clicked
    GameStates targetState;

    //Whether we are moused over the button
    bool mouseOver;
};

#endif
MenuButton.h(派生类)
#ifndef MENUBUTTON_H
#define MENUBUTTON_H

#include "button.h"

using namespace std;

class MenuButton :
    public Button
{
public:
    MenuButton(void);

    MenuButton(int x, int y, int w, int h, string text, GameStates state);

    void handleEvents();

    void render();

    ~MenuButton(void);
};

#endif
Title.h(正在创建按钮并引发错误的状态)
#ifndef TITLE_H
#define TITLE_H

#include "GameState.h"
#include "SDL.h"
#include "SDL_image.h"
//#include "SDL_Mixer.h"
#include "Functions.h"
#include "Globals.h"
#include "Constants.h"
#include "MenuButton.h"
#include <iostream>
#include <string>

using namespace std;

class Title :
    public GameState
{
public:
    Title(void);

    //Handles intro events
    void handleEvents();

    //Handles intro logic
    void logic();

    //Handles intro rendering
    void render();

    ~Title(void);
private:
    SDL_Surface *background;
    MenuButton *testButton; //NOTE: This is the line throwing the errors
    //Mix_Music *music;
};

#endif
谢谢您的帮助!〜

最佳答案

似乎编译器不知道MenuButton是什么。可能是这种情况的一个原因是MENUBUTTON_H也由另一个 header 定义。更有可能的是,像Globals.h这样的东西也包括"title.h",即您的系统中有一个依赖循环。如果您知道类是周期性依赖的,那么最好删除这些循环。有很多方法可以做到这一点。即使您当前认为您需要循环依赖关系,它也不是一件好事,而且可能也不是必需的(John Lakos撰写的《大型C++设计》一书包含了许多有关如何打破依赖关系循环的信息)。

如果您不知道循环的来源,我建议在编译器中使用-E(或/E)标志:此选项通常在经过预处理后产生转换单元。它将包含以某种形式输入哪个文件的指示。预处理输出的外观取决于编译器,但是您将能够看到编译器可以看到的内容,并且可以追踪为什么未声明MenuButton

作为一种简便的方法,您还可以确保声明了MenuButton:要形成一个指针,不需要定义它。您在实际访问指针时已经看到一个定义就足够了。声明看起来像这样:

class MenuButton;

..并可以在每个翻译单元中使用MenuButton重复以声明MenuButton的指针或引用成员。您甚至可以仅通过声明来声明按值返回或传递MenuButton的函数。当然,当您要实际使用类型时,需要查看其定义。

10-07 19:46