如何在 C 中同时隐藏结构信息的同时克服循环依赖?

How to overcome circular dependency while achive struct information hiding at the same time in C?

如您所见,我想在逻辑上将 table 与游标实现分开。此外,我想对用户隐藏 table 和光标信息。但是,这样做会产生如下编译错误

./table.h:10:1: error: unknown type name 'Cursor'

另一种解决方案是转发声明结构或将结构声明放入头文件中。但是它们不是很优雅。

或者我只是不知道如何以“更好”的方式使用前向声明。

还有其他方法可以实现我在这里尝试做的事情吗?

任何帮助将不胜感激。

cursor.h

#ifndef CURSOR_H
#define CURSOR_H

#include "table.h"

typedef struct Cursor_t Cursor; //struct data hiding

//struct Table; //alternative solution: forward declaration
//struct Table* cursor_get_table(Cursor* cursor);
Table* cursor_get_table(Cursor* cursor);
#endif

cursor.c

#include "cursor.h"

typedef struct Cursor_t {
    Table* table;
} Cursor;

//struct Table* cursor_get_table(Cursor* cursor) { //alternative solution
Table* cursor_get_table(Cursor* cursor) {
    return cursor->table; //warning: incompatible pointer types returning 'Table *'...
}

table.h

#ifndef TABLE_H
#define TABLE_H

#include "cursor.h"

typedef struct Table_t Table; //struct data hiding

//struct Cursor; //alternative solution: forward declaration
//struct Cursor* table_start(Table* table);
Cursor* table_start(Table* table); //error: unknown type name 'Cursor'
#endif

table.c

#include "table.h"

typedef struct Table_t {
} Table;

//struct Cursor* table_start(Table* table) { //alternative solution
Cursor* table_start(Table* table) {
    return 0;
}

main.c

#include <stdio.h>

#include "cursor.h"
#include "table.h"

int main() {
    Table* table;
    Cursor* cursor;
    printf("hello world\n");
    return 0;
}

请注意 main.c 只是一个测试代码。我不想在这里完成任何有意义的事情。

使用指针的前向结构声明也是一种数据隐藏形式。 cursor.c 无法访问 Table interna,并包含 Cursor 定义。

这允许在不重新编译用法的情况下更改实现(通过 makefile)。

您可能需要介于 cursor.c 和 table.c 之间的函数,但它甚至可以放在 cursor_table.h 或您喜欢的任何样式中。存在紧密耦合的“类”。

您的头文件中存在循环依赖关系,因此只有其中一个包含在另一个中,具体取决于您正在编译哪个文件。

两个头文件都需要看到对方类型的前向声明,因此使用这些类型创建第三个头文件并将其包含在现有头文件中。

types.h

#ifndef TYPES_H
#define TYPES_H

typedef struct Cursor_t Cursor;
typedef struct Table_t Table; 

#endif

cursor.h

#ifndef CURSOR_H
#define CURSOR_H

#include "types.h"

Table* cursor_get_table(Cursor* cursor);
#endif

table.h:

#ifndef TABLE_H
#define TABLE_H

#include "types.h"

Cursor* table_start(Table* table);
#endif

您的 .c 文件将具有结构定义,但没有 typedef 因为它已经存在。