用C语言实现数据隐藏访问说明符

时间:2016-07-12 11:16:04

标签: c oop

是否有办法实现访问说明符,例如" private"," protected"用C语言。我在互联网上遇到了关于使用"静态"和" ifdefs"使功能仅在某些其他功能中可用。

除此之外,是否有任何C实现相当于在C ++类中使用私有和受保护的访问说明符?

2 个答案:

答案 0 :(得分:5)

C没有访问说明符。向调用者隐藏内容的唯一方法是不在标题中提供声明。

您可以在翻译单元中将其设为静态:

myapi.h

extern int visibleVariable;
void visibleFunction();

myapi.c

int visibleVariable;
static int invisibleVariable;
void visibleFunction() {
    ...
}
static void invisibleFunction() {
    ...
}

您还可以通过将struct放在实现文件中来隐藏它的定义。这样,结构的所有字段都将是翻译单元的私有字段。这种方法的缺点是您的API用户无法声明struct类型的变量,因此他们需要通过指针处理您的struct

C没有继承概念,因此没有protected访问权限。

答案 1 :(得分:4)

C没有用户可定义的名称空间或访问说明符。由于您排除(ab)使用预处理器,因此尝试访问“类”的私有部分时获取编译器错误的唯一方法是不使用.h文件来公开“私有”内容。它们仍然可以放入“私有”单独的.h文件(由模块或库自己的.c文件包含,但不应包含在应用程序代码中),或隐藏在#ifdef后面(需要特殊定义才能激活) “私人”部分。)

隐藏事物的一种常见方法是使用不透明的结构AKA不透明指针。对于该方法,模块或库外部的代码仅具有指向结构的指针,但没有结构定义。然后它使用模块提供的函数来获取实例,访问它,最后释放它。

使用这种方法,您可以轻松获得公共接口:您在公共.h文件中提供的功能,以及在那里有定义的任何公共支持结构。私有接口是完整结构定义可见的代码,以及不在公共.h文件中的任何函数。

受保护的访问意味着继承,当使用C手动实现时,它通常与C ++的工作方式非常不同,并且在本答案中涵盖的主题过于宽泛。最接近这个可能是有几个.h文件,它们提供了几个级别的“公共”访问,然后程序员有责任不让它们遇到问题。

这种方法的好处是,如果更改了struct,则不需要修改(甚至重新编译)使用该模块的其他代码。通常struct甚至可能是一个联合,然后模块的函数将根据实际类型进行分支,所有来自使用它的代码的invisibe。另一个好处是,模块可以控制结构的创建,因此它可以例如具有结构池并避免使用堆,所有这些对应用程序代码都是不可见的。一个缺点是,你不能有内联函数(因为.h文件中的内联函数体需要结构定义,我们试图在这里隐藏),这会在性能受到关注的情况下阻止一些不错的编译器优化。

示例(为此答案编写的未经测试的代码):

module.h中:

// ...other standard header file stuff ...

// forward declaration of struct
struct module_data;

// "constructor" function
struct module_data *module_initialize_data(int value);

// modification function
int module_update_data(struct module_data *data, int adjust);

// "destructor" function
void module_release(struct module_data *data);

的module.c

#include "module.h"

// struct definition only in the .c file
struct module_data {
   int value;
};

struct module_data *module_initialize_data(int value) {
    struct module_data *data = malloc(sizeof(*data));
    data->value = value;
    return data;
}

int module_update_data(struct module_data *data, int adjust) {
    data->value += adjust;
    return data->value;
}

void module_release(struct module_data *data) {
    free(data);
}

相关维基百科链接供参考: