这是我第一次在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
的函数。当然,当您要实际使用类型时,需要查看其定义。