如何解决头文件之间的这种相互依赖性?

时间:2019-05-04 00:31:06

标签: c header circular-dependency

请注意,关于SO的循环依赖有几个问题(包括我曾经问过的一个问题),但是我觉得这些问题都没有帮助我解决这个问题。

请考虑以下两个文件:

table.h

#ifndef s_table_h
#define s_table_h

#include "value.h"
#include "object.h"

typedef struct {
    ObjectString* key;
    Value value;
} Entry;

typedef struct {
    int capacity;
    int count;
    Entry* entries;
} Table;

void initTable(Table* table);
void setTable(Table* table, ObjectString* key, Value value);
bool getTable(Table* table, ObjectString* key, Value* out);

#endif

object.h

#ifndef s_object_h
#define s_object_h

#include "common.h"
#include "table.h"

typedef enum {
    OBJECT_STRING
} ObjectType;

typedef struct {
    ObjectType type;
    Table attributes;
} Object;

typedef struct {
    Object base;
    char* chars;
    int length;
} ObjectString;

bool stringsEqual(ObjectString* a, ObjectString* b);

#endif

如您所见,这两个相互依赖:table.h需要ObjectString*,而object.h需要具体的Table。两个相应的.c实现文件分别访问ObjectString*Table的具体成员。

解决此问题的推荐方法是什么?通常,在C中解决此类问题的通用方法是什么?

请仅解决技术方面的问题,而不是软件设计方面的问题。

2 个答案:

答案 0 :(得分:1)

我想您可能会说我在这里解决软件设计方面的问题,但是我不知道如何在不稍微重构代码的情况下做到这一点。即,通过暂时避免typedef。 (尽管我建议永久转储typedef。)对于您的特殊情况,table.h不需要知道ObjectString是什么,因为它仅使用指向它的指针。因此,您不能简单地不在table.h中导入“ object.h”,而是编写:

object.h:

#ifndef s_object_h
#define s_object_h

#include "common.h"
#include "table.h"

typedef enum {
    OBJECT_STRING
} ObjectType;

typedef struct {
    ObjectType type;
    Table attributes;
} Object;

struct ObjectString {
    Object base;
    char* chars;
    int length;
};

typedef struct ObjectString ObjectString;

bool stringsEqual(ObjectString* a, ObjectString* b);

#endif

table.h:

#ifndef s_table_h
#define s_table_h

#include "value.h"

typedef struct {
    struct ObjectString* key;
    Value value;
} Entry;

typedef struct {
    int capacity;
    int count;
    Entry* entries;
} Table;

void initTable(Table* table);
void setTable(Table* table, struct ObjectString* key, Value value);
bool getTable(Table* table, struct ObjectString* key, Value* out);

#endif

答案 1 :(得分:0)

也许您可以这样做,将table.h和object.h放到一个名为both.h的文件中,不再需要table.h和object.h,只使用both.h:

#ifndef s_table_h
#define s_table_h

#include "value.h"
#include "common.h"

//#include "object.h"
//#include "table.h"


typedef struct A ObjectString;      // add

typedef struct {
    ObjectString* key;
    Value value;
} Entry;

typedef struct {
    int capacity;
    int count;
    Entry* entries;
} Table;





typedef enum {
    OBJECT_STRING
} ObjectType;

typedef struct {
    ObjectType type;
    Table attributes;
} Object;

typedef struct A {     // modify to typedef struct A
    Object base;
    char* chars;
    int length;
} ObjectString;

bool stringsEqual(ObjectString* a, ObjectString* b);
void initTable(Table* table);
void setTable(Table* table, ObjectString* key, Value value);
bool getTable(Table* table, ObjectString* key, Value* out);

#endif