Проблема со структурами, где их разместить и как ссылаться на них в заголовках? - PullRequest
3 голосов
/ 01 июля 2010

ОК, сейчас у меня дилемма, и ни мое знание C (которое в любом случае не самое большое), ни всемогущий Google, похоже, не могут мне помочь в этом:

У меня есть несколько структур для прототипа игры:

  • Map (Ммм ... Карта ..)
  • Chara (База для врагов игроков)
  • Player (Игрок)

Теперь проблема в том, что Map нужна ссылка на Player, который находится на нем, Player создается, давая ему Map и Chara, а Chara требуется Map тоже.

Если я объявляю структуры в заголовочных файлах и заключаю их в #ifndef, я запускаю циклический цикл зависимости, когда включаю заголовки из других заголовков.

Когда я объявляю структуры в файлах .c, я использую extern struct Map map и т. Д., Но затем я сталкиваюсь с проблемой, подобной invalid use of incomplete declaration или forward declaration of struct XXX.

Здесь 4 часа утра, и я хотел бы больше времени уделить переписыванию движка (который уже существует как в Python, так и в JavaScript ... да, у меня слишком много времени!), А не пробуя каждую возможную комбинацию поисковых терминов до конца ночи.

Я знаю, что это может быть ДЕЙСТВИТЕЛЬНО легкая вещь, но здесь 30 ° C, поэтому, пожалуйста, смилуйтесь с моими "навыками" C ^^

EDIT
Поскольку в моей задаче использовались typedefs, а ответ caf не включал их, мне пришлось немного поиграться с этим, чтобы все заработало. Поэтому, чтобы помочь людям, которые могут найти этот ответ через SE, я добавлю код ниже:

map.h

typedef struct _Player Player;

typedef struct _Map {
    ...
    Player *player;
    ...
} Map;

map.c

// include both player.h and chara.h

player.h

typedef struct _Map Map;
typedef struct _Chara Chara;

typedef struct _Player {
    Chara *chara;
    ...
} Player;

Player *player_create(Map *map, int x, int y);

player.c

// include player.h, chara.h and map.h

Ответы [ 2 ]

3 голосов
/ 01 июля 2010

Это работает, если ваши структуры содержат только указатели на другие структуры:

map.h

#ifndef _MAP_H
#define _MAP_H

struct player;

struct map {
    struct player *player;
    ...
};

#endif /* _MAP_H */

chara.h

#ifndef _CHARA_H
#define _CHARA_H

struct map;

struct chara {
    struct map *map;
    ...
};

#endif /* _CHARA_H */

player.h

#ifndef _PLAYER_H
#define _PLAYER_H

struct map;
struct chara;

struct player {
    struct map *map;
    struct chara *chara;
    ...
};

#endif /* _PLAYER_H */

Если одна из ваших структур содержит фактические экземпляры других структур (включая массивы), тогда эта структура должна будет #include другой заголовок тоже.Например, если map содержит массив игроков:

map.h

#ifndef _MAP_H
#define _MAP_H

#include "player.h"

struct map {
    struct player p[10];
    ...
};

#endif /* _MAP_H */

Вы должны быть осторожны с круговыми включениями.Если вы включили map.h в player.h, то вы не могли бы включить player.h в другой исходный файл до map.h - так что вы бы этого не сделали.

0 голосов
/ 01 июля 2010

Убедитесь, что ваши ссылки являются указателями, а не фактическими копиями объектов, и вы должны быть в состоянии заранее объявить их заранее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...