如何在 C 中为结构实现受保护的访问修饰符
How to implement protected access modifier for struct in C
我想自己访问结构成员,不希望其他人看到详细信息。
简单地说,我的意思是 Java.
中受保护的访问修饰符
我有一个名为 linkedlist.c 的文件,它的结构如下:
struct listNode
{
int data;
struct listNode *next;
};
struct linkedlist
{
ListNode *head;
};
和头文件 linkedlist.h 如下所示:
typedef struct listNode ListNode;
typedef struct linkedlist LinkedList;
但我无法在另一个名为 priority_queue.c 的文件中使用结构成员,因为结构定义仅在 .c 文件中。
如何实现这些我自己可以访问成员但其他程序员只能看到类型 LinkedList 和 ListNode 的结构?
简短回答,您不能保护结构中的变量,您应该考虑使用 类,或创建方法(函数)来更新和读取您添加逻辑以防止访问的结构的成员.您提供给其他开发人员的文档将仅包含“允许的方法”
请记住,任何人都可以获得指向您的结构的指针,并且由于他们拥有该类型,因此他们可以以他们想要的任何方式访问您的结构(因为任何人都可以在 his/her 代码中重新定义您的结构)。
正如我在简短的 comment 中指出的那样,我认为您将需要两个 header(或者,我会使用两个 header 来解决这个问题)。一个header定义了public接口。另一个定义了受保护的接口。第二个应该包括第一个以确保一致性。您的代码使用受保护的接口。其他人的代码都使用public接口。
我的意思是 public 接口是不透明类型,“受保护”接口定义了私有细节。接口中的函数将使用指向不透明类型的指针,因此您的 public header 可能是:
linkedlist.h
#ifndef LINKEDLIST_H_INCLUDED
#define LINKEDLIST_H_INCLUDED
typedef struct listNode ListNode;
typedef struct linkedlist LinkedList;
typedef int Data;
extern LinkedList *ll_create(void);
extern ListNode *ln_create(Data value);
extern void ll_destroy(LinkedList *ll);
extern void ln_destroy(ListNode *ln);
…
#endif /* LINKEDLIST_H_INCLUDED */
你还有第二个 header 来提供受保护的访问权限,称之为 linkedlistp.h
:
#ifndef LINKEDLISTP_H_INCLUDED
#define LINKEDLISTP_H_INCLUDED
#include "linkedlist.h"
struct listNode
{
Data data;
ListNode *next;
};
struct linkedlist
{
ListNode *head;
};
#endif /* LINKEDLISTP_H_INCLUDED */
您的源文件 linkedlist.c
将包含 linkedlistp.h
;任何其他需要参与数据结构内部的源文件也是如此。因此,普通用户代码只能访问 linkedlist.h
并且只能使用 public 接口。
它主要是在 header 中重塑私有实现细节,它可以被多个特权源文件使用,而不是像更常见的那样隐藏在单个源文件中(就像你现在拥有的那样)。它不强制分离——除非你不分发私有 header,任何人都可以通过包含受保护的 header 来决定他们的代码对内部是私有的。在组织内的项目中,您可以制定规则来禁止使用受保护的 header。如果您将代码作为开源项目发布,您将无法控制人们对受保护的内容进行的操作 header.
注意保护是'all or nothing';没有 half-way 房子。代码要么知道结构的所有内部结构(因为它包含 linkedlistp.h
),要么对结构的内部结构一无所知(因为它只包括 linkedlist.h
)。
应审查命名约定。您的结构标签有不同的大写字母,这不好;我留下了你的拼写。我猜想 'linked list' 和 'list node' 函数的 ll_
和 ln_
前缀——你可以使用任何你喜欢的,或多或少的冗长。文件名后缀 p
(如 linkedlistp.h
)是一种简洁但中等常用的方式来指示 header 是 'private' 或 'protected'。您可以选择一个可能更详细的替代名称。
我想自己访问结构成员,不希望其他人看到详细信息。 简单地说,我的意思是 Java.
中受保护的访问修饰符我有一个名为 linkedlist.c 的文件,它的结构如下:
struct listNode
{
int data;
struct listNode *next;
};
struct linkedlist
{
ListNode *head;
};
和头文件 linkedlist.h 如下所示:
typedef struct listNode ListNode;
typedef struct linkedlist LinkedList;
但我无法在另一个名为 priority_queue.c 的文件中使用结构成员,因为结构定义仅在 .c 文件中。
如何实现这些我自己可以访问成员但其他程序员只能看到类型 LinkedList 和 ListNode 的结构?
简短回答,您不能保护结构中的变量,您应该考虑使用 类,或创建方法(函数)来更新和读取您添加逻辑以防止访问的结构的成员.您提供给其他开发人员的文档将仅包含“允许的方法” 请记住,任何人都可以获得指向您的结构的指针,并且由于他们拥有该类型,因此他们可以以他们想要的任何方式访问您的结构(因为任何人都可以在 his/her 代码中重新定义您的结构)。
正如我在简短的 comment 中指出的那样,我认为您将需要两个 header(或者,我会使用两个 header 来解决这个问题)。一个header定义了public接口。另一个定义了受保护的接口。第二个应该包括第一个以确保一致性。您的代码使用受保护的接口。其他人的代码都使用public接口。
我的意思是 public 接口是不透明类型,“受保护”接口定义了私有细节。接口中的函数将使用指向不透明类型的指针,因此您的 public header 可能是:
linkedlist.h
#ifndef LINKEDLIST_H_INCLUDED
#define LINKEDLIST_H_INCLUDED
typedef struct listNode ListNode;
typedef struct linkedlist LinkedList;
typedef int Data;
extern LinkedList *ll_create(void);
extern ListNode *ln_create(Data value);
extern void ll_destroy(LinkedList *ll);
extern void ln_destroy(ListNode *ln);
…
#endif /* LINKEDLIST_H_INCLUDED */
你还有第二个 header 来提供受保护的访问权限,称之为 linkedlistp.h
:
#ifndef LINKEDLISTP_H_INCLUDED
#define LINKEDLISTP_H_INCLUDED
#include "linkedlist.h"
struct listNode
{
Data data;
ListNode *next;
};
struct linkedlist
{
ListNode *head;
};
#endif /* LINKEDLISTP_H_INCLUDED */
您的源文件 linkedlist.c
将包含 linkedlistp.h
;任何其他需要参与数据结构内部的源文件也是如此。因此,普通用户代码只能访问 linkedlist.h
并且只能使用 public 接口。
它主要是在 header 中重塑私有实现细节,它可以被多个特权源文件使用,而不是像更常见的那样隐藏在单个源文件中(就像你现在拥有的那样)。它不强制分离——除非你不分发私有 header,任何人都可以通过包含受保护的 header 来决定他们的代码对内部是私有的。在组织内的项目中,您可以制定规则来禁止使用受保护的 header。如果您将代码作为开源项目发布,您将无法控制人们对受保护的内容进行的操作 header.
注意保护是'all or nothing';没有 half-way 房子。代码要么知道结构的所有内部结构(因为它包含 linkedlistp.h
),要么对结构的内部结构一无所知(因为它只包括 linkedlist.h
)。
应审查命名约定。您的结构标签有不同的大写字母,这不好;我留下了你的拼写。我猜想 'linked list' 和 'list node' 函数的 ll_
和 ln_
前缀——你可以使用任何你喜欢的,或多或少的冗长。文件名后缀 p
(如 linkedlistp.h
)是一种简洁但中等常用的方式来指示 header 是 'private' 或 'protected'。您可以选择一个可能更详细的替代名称。