多个包含错误,找不到解决方案

时间:2012-06-17 11:48:48

标签: c++ file redefinition inclusion

我最近一直在努力解决多个文件包含错误。 我正在开发一个太空街机游戏,并将我的类/对象分成不同的.cpp 文件并确保一切仍然可以正常工作我已经构建了以下头文件:

#ifndef SPACEGAME_H_INCLUDED
#define SPACEGAME_H_INCLUDED
//Some Main constants
#define PI 3.14159265


//Standard includes
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <math.h>
#include <string.h>
#include <iostream>
#include <vector>
using namespace std;

//SDL headers
#include "SDL.h"
#include "SDL_opengl.h"
#include "SDL_mixer.h"
#include "SDL_image.h"

//Classes and project files
#include "Player.cpp"
#include "planet.cpp"
#include "Destructable.cpp"
#include "PowerUp.cpp"
#include "PowerUp_Speed.cpp"

#endif // SPACEGAME_H_INCLUDED

在我的每个文件的顶部,我包含(仅)此头文件,其中包含所有.cpp文件和标准包含。

但是,我有一个Player / Ship类,它给了我“重新定义Ship类”类型的错误。我最终通过在类定义文件中包含预处理器#ifndef和#define命令找到了一种解决方法:

#ifndef PLAYER_H
#define PLAYER_H
/** Player class that controls the flying object used for the space game */
#include "SpaceGame.h"


struct Bullet
{
  float x, y;
  float velX, velY;
  bool isAlive;
};

class Ship
{
    Ship(float sX,float sY, int w, int h, float velocity, int cw, int ch)
    {
        up = false; down = false; left = false; right = false;
        angle = 0;
....
#endif

通过这种解决方法,我丢失了'class / struct redefinition'erorrs但它在我的类文件PowerUp_Speed中给了我奇怪的错误,它需要Ship类:

#include "SpaceGame.h"

class PowerUp_Speed : public PowerUp
{

    public:
        PowerUp_Speed()
        {
            texture = loadTexture("sprites/Planet1.png");
        }

        void boostPlayer(Ship &ship)
        {
            ship.vel += 0.2f;
        }
};

我遇到了以下错误:'无效使用不完整类型'struct Ship''和 ''struct ship'的前瞻声明'

我相信这些错误的根源仍然是我的麻烦,多个文件包含错误。 我描述了我为减少错误量而采取的每一步,但到目前为止都没有 我在Google上发现的帖子帮助了我,这就是为什么我礼貌地问你是否有人可以帮助我找到问题的根源和修复。

1 个答案:

答案 0 :(得分:9)

通常,您不包含cpp文件 您只需要包含头文件!

当您包含cpp文件时,您最终会破坏 One Definition Rule(ODR) 通常,您的头文件(.h)将定义类/结构等,您的源(.cpp)文件将定义成员函数等。
根据 ODR ,您只能为每个变量/函数等定义,包括多个文件中的相同cpp文件会创建多个定义,从而打破ODR。

  

你应该怎么做?

请注意,为了能够创建对象或调用成员函数等,您需要做的就是包含头文件,该文件在源文件中定义需要创建对象的类等。您不需要包含源文件随处可见。

  

远期声明怎么样?

始终首选使用前向声明类或结构而不是包含头文件,这样做具有明显的优势,例如:

  • 缩短编制时间
  • 没有污染全局命名空间。
  • 没有潜在的预处理程序名称冲突。
  • 二进制大小没有增加(在某些情况下虽然并非总是如此)

但是,一旦转发声明类型,您只能对其执行有限的操作,因为编译器将其视为不完整类型。所以你应该try to Forward declarations always but you can't do so always