【问题标题】:Is there any workaround for making a structure member somehow 'private' in C?是否有任何解决方法可以使结构成员在 C 中以某种方式“私有”?
【发布时间】:2010-03-26 19:27:06
【问题描述】:

我正在用 C 语言开发一个简单的库,供我自己和一些朋友个人使用。

我目前有一个包含一些成员的 C 结构,这些成员应该以某种方式对应用程序的其余部分隐藏,因为它们仅在内部使用。不小心修改其中一个成员可能会使库“疯狂”。

是否有任何“解决方法”来隐藏这些成员以使其无法访问?

【问题讨论】:

  • 似乎想法是将结构'隐藏'在.c文件中,同时在.h文件中声明访问接口。我希望我做对了!

标签: c encapsulation


【解决方案1】:

通常的技术是这样的:

/* foo.h */
typedef struct Foo Foo;

Foo *foo_create(...);

void foo_bark(Foo* foo, double loudness);

/* foo.c */
struct Foo {
  int private_var;
};

您可以通过在标头中定义 Foo 并在 .c 文件中定义 FooPrivate 来部分隐藏数据成员:

struct FooPrivate {
  Foo public_stuff;
  int private_var;
}

但是你的实现必须在 Foo 和 FooPrivate 之间来回转换,我发现它是一个皇家 PITA,如果你以后改变主意并想要将某些东西设为私有,这将是一个维护负担。除非您想从代码中提取每个最后一个 CPU 周期,否则只需使用访问器函数。

【讨论】:

  • 你能说得更具体些吗? :)
  • @nomemory,只提供更新特定字段的接口,不暴露结构。例如 foo_create 和 foo_bark 函数。
  • 这会隐藏struct整个 内容,而不是特定字段,因此需要访问器。
【解决方案2】:

Marcelo Cantos 已经给你答案了。有关更多详细信息,您应该查看 FILE 结构如何有效地隐藏在大多数基础库中。

您会注意到 FILE 结构本身对用户是不可用的,只有接口和不透明的 FILE * 对我们可用。

【讨论】:

    【解决方案3】:

    基本上,这个想法是用哈希之类的东西重命名结构的变量 并编写函数(类似于 OO 语言中的模仿方法)来访问它们。 理想情况下,您应该在结构中有指向这些函数的函数指针,这样您就不会 必须调用一个外部函数并将其传递给您希望添加的成员。 然而,函数指针语法并不是最漂亮的。 一个简单的例子可以澄清 Marcelo 之前所说的内容:

    struct Car {
        int _size;
        char _colour[10];
    
    };
    
    typedef struct Car Car;
    
    
    int main (int argc, char **argv) {   
        Car *myCar= malloc(sizeof(Car));
        myCar->_size=5; /* accessing it directly just to set up a value, you shold have an
                           accessor function really */
    
        printf("car size is: %i \n",getCarSize(myCar));
        free(myCar);
    }
    
    
    
    
    int getCarSize(Car *myCar) {
         return myCar->_size;
    }
    

    【讨论】:

    • 在不知道结构内容的情况下,代码可以传递指向struct foo 的指针,但是创建struct foo 类型的变量需要定义其内容。如果两个联合的大小和对齐方式受同一类型约束(例如 long long[4]),是否定义了不同联合类型之间的类型双关语?
    【解决方案4】:

    我同意 Marcelo Cantos,但也建议在“公共”结构内简单地添加一个指针,该指针指向“私有”内容,即:

    /* foo.h */
    typedef struct Bar Bar;
    typedef struct Foo 
    {
       int public;
       Bar* private;
    } Foo;
    
    Foo *foo_create(...);
    
    void foo_bark(Foo* foo, double loudness);
    
    /* foo.c */
    struct Bar 
    {
      int private_var;
    };
    

    这种方法有点像“pimpl”理念。到目前为止,最简单的方法是按照 Marcelo Cantos 的建议进行操作。

    【讨论】:

    • 谢谢,看来C语言可以支持一些“oop”功能,在程序员方面稍加努力:)。
    猜你喜欢
    • 2015-12-07
    • 2014-12-18
    • 1970-01-01
    • 2013-09-22
    • 2020-02-22
    • 1970-01-01
    • 1970-01-01
    • 2013-11-23
    • 2020-09-24
    相关资源
    最近更新 更多