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

Joe*_*ewd 4 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
Run Code Online (Sandbox Code Playgroud)

在我的每个文件的顶部,我包括(仅)此头文件,其中包含所有.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
Run Code Online (Sandbox Code Playgroud)

通过这种解决方法,我丢失了'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;
        }
};
Run Code Online (Sandbox Code Playgroud)

我一直遇到以下错误:' 无效使用不完整类型'struct Ship' '和'struct declaration of'struct ship' '

我相信这些错误的起源仍然存在于多文件包含错误的麻烦中.我描述了我为减少错误数量而采取的每一步措施,但到目前为止,我在谷歌上发现的所有帖子都没有帮助我,这就是为什么我礼貌地问你是否有人能帮助我找到原因.问题和解决方法.

Alo*_*ave 9

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

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

你应该怎么做?

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

前言宣言怎么样?

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

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

但是,一旦转发声明类型,您只能对其执行有限的操作,因为编译器将其视为不完整类型.因此,您应该始终尝试转发声明,但始终不能这样做.