如何在 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
因为它已经存在。
如您所见,我想在逻辑上将 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
因为它已经存在。