【问题标题】:How to avoid header file duplication?如何避免头文件重复?
【发布时间】:2012-04-30 13:02:06
【问题描述】:

在我的程序中,我得到了两个名为“invader.h”和“game.h”的头文件。在 game.h 中我包含了invader.h,因为我想将当前游戏实例的指针传递给一个入侵者实例。我还在invader.h 中包含了game.h,但是我得到了编译错误。如果我从invader.h 中删除game.h,它工作正常。我已经在每个头文件中添加了包含保护。根据我目前发现的情况,我在invader.h 中添加了游戏类的前向声明,因为我需要的是一个指向invancer.h 中游戏实例的指针。但是当我想在invader.cpp中调用一个游戏函数时,它说不允许指向不完整类类型的指针。我应该怎么做才能解决这个问题?

游戏.h

#ifndef GAME_H
#define GAME_H
#include "Tank.h"
#include "Invader.h"
#include "Block.h"
#include "Bullet.h"

class Game
{
private:
Tank tank;
Invader invaders[11][5];
Block blocks[4];
bool logicRequiredThisLoop = false;
public:
Game();
void initEntities();
Tank* getTank(){return &tank;};
Invader* getInvaders(){return &invaders[0][0];};
Block* getBlocks(){return &blocks[0];};
void updateLogic();
};
#endif

入侵者.h

#ifndef INVADER_H
#define INVADER_H
#include "Entity.h"
class Game; //forward declaration of class Game
class Invader: public Entity
{
private:
Game* game;
public:
Invader(){};
Invader(Game*,char*,int,int,int,int,int,int);
void move(long delta);
void doLogic();
};
#endif

入侵者.cpp

#include "Invader.h"
Invader::Invader(Game* game,char* sprite,int x,int y,int dx,int dy,int width,int height):Entity(sprite,x,y,dx,dy,width,height)
{
this->game = game;
}

void Invader::move(long delta)
{
if ((dx<0)&&(x<=10))
{
    game->updateLogic();
}
if ((dx>0)&&(x>=390))
{
    dx = -dx;
    y -= dy;
}

x+=dx;
}

在 Invader.cpp 中,当我尝试调用 Game 类的成员函数 updateLogic() 时,出现错误,指出不允许指向不完整类的指针

其实简单来说这里我最想知道的是:在我的代码中Game类有一个入侵者类型的成员变量,那么入侵者类中如何调用Game类的成员函数呢?li,e我说if我在 Game.h 中包含 Invader.h 并在 Invader.h 中包含 Gameh.h 会发生编译错误。

这就是我在 Invader.h 中包含 Game.h 时得到的结果:

1>ClCompile:
1>  Invader.cpp
1>c:\users\tony\documents\info3220\spaceinvader\spaceinvader\basicwogl\game.h(13): error C2146: syntax error : missing ';' before identifier 'invaders'
1>c:\users\tony\documents\info3220\spaceinvader\spaceinvader\basicwogl\game.h(13): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\tony\documents\info3220\spaceinvader\spaceinvader\basicwogl\game.h(13): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\tony\documents\info3220\spaceinvader\spaceinvader\basicwogl\game.h(21): error C2143: syntax error : missing ';' before '*'
1>c:\users\tony\documents\info3220\spaceinvader\spaceinvader\basicwogl\game.h(21): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\tony\documents\info3220\spaceinvader\spaceinvader\basicwogl\game.h(21): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\tony\documents\info3220\spaceinvader\spaceinvader\basicwogl\game.h(21): warning C4183: 'getInvaders': missing return type; assumed to be a member function returning 'int'
1>c:\users\tony\documents\info3220\spaceinvader\spaceinvader\basicwogl\game.h(21): error C2065: 'invaders' : undeclared identifier

【问题讨论】:

  • @CarlNorum 我发布源代码
  • @JoachimPileborg:他已经做了“它说不允许指向不完整类类型的指针”
  • 您能否在问题中添加您得到的错误,逐字(即复制粘贴)?

标签: c++


【解决方案1】:

我应该怎么做才能解决这个问题?
首先了解不完整类型的含义:

What leads to incomplete types?

如果你不能在类型不完整的情况下使用前向声明,那么你应该重新访问你的设计,因为那里有问题。

如果您需要更详细的答案,您需要提供源代码。

编辑:
您需要在Invader.cpp 中包含Game.h

//Invader.cpp

#include "Invader.h"
#include "Game.h"

【讨论】:

  • 原来是这样的,但是出现错误,我在网上搜索了一下,头文件好像不能互相包含。这就是我在这里使用前向声明的原因
  • @tonyaziten:“发生错误..” 什么错误?只要您有适当的包含保护措施,这应该可以工作。
  • 是的,我一开始也是这么想的,但是编译失败我在帖子中附加了错误
  • @tonyaziten:再说一次,我(或任何人)都不能评论 compile failed,这里没有魔术师相信我。你需要提供实际的错误。
  • @tonyaziten:您需要按照我在答案中提到的完全相同的顺序(在 cpp 文件中)包含标题。您将其包含在头文件中。仔细阅读答案。跨度>
【解决方案2】:

我将参考我现在本地盒子里的两个文件来解释这一点。

server.hworker.h

服务器.h:

#ifndef SERVER_H_
#define SERVER_H_

typedef struct _conf conf;
typedef struct _worker worker;
typedef struct _logger logger;

typedef struct _server server;
struct _server {
    /* config */
    conf *cfg;

    /* socket */
    int fd;
    struct event_base *base;
    struct event *signal;

    /* workers */
    worker **w;

    /* log */
    logger *log;
};
...
...
#endif /* SERVER_H_ */

worker.h

#ifndef WORKER_H_
#define WORKER_H_

#include <pthread.h>

typedef struct _server server;

typedef struct _worker worker;
struct _worker {
    pthread_t t;

    struct event_base *base;
    struct evhttp *http;

    server *s;
};
...
...
#endif /* WORKER_H_ */

如您所见,服务器结构和工作结构都相互引用,这可以通过.h 文件顶部的前向声明来解决:例如

typedef struct _worker worker; 

server.h 的顶部足以让它引用工作结构。 您可能需要在此处查看完整文件以供进一步参考:https://github.com/abhinavsingh/pulsar/tree/master/include

希望对您有所帮助。

【讨论】:

  • 那么这是下面Als指出的代码设计问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-24
  • 2013-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多