c - 将结构划分为私有(private)和公共(public)部分?

标签 c struct private-methods

在 C++ 和 Java 中,数据结构可以有 privatepublicprotected 区域。我想将这个概念移植到我正在编写的 C 语言程序中。

在 C struct 中是否有任何用于实现私有(private)或 protected 函数指针和数据字段的习惯用法? 我知道 C struct 是公共(public)的,我正在寻找一个习惯用法来帮助隐藏一些实现细节并强制用户使用公共(public)接口(interface)。

注意:语言已由商店选择,因此我无法在 C 中实现面向对象的概念。

谢谢。

最佳答案

如您所知,您不能这样做。但是,有些习语可以产生类似的效果。

C 允许您做类似于面向对象设计中所谓的“pimpl”习语的事情。您的结构可以有一个不透明的指针,指向另一个前向声明的结构,该结构充当该结构的私有(private)数据。对结构进行操作的函数代替了成员函数,可以拥有私有(private)成员的完整定义,并且可以使用它,而代码的其他部分则不能。例如:

在标题中,foo.h:

  struct FooPrivate;

  struct Foo {
     /* public: */
       int x; 
       double y;
     /* private: */
       struct FooPrivate* p;
  };

  extern struct Foo* Foo_Create(); /* "constructor" */

  extern void Foo_DoWhatever(struct Foo* foo); /* "member function" */

在实现中,foo.c:

  struct FooPrivate {
     int z;
  };

  struct Foo* Foo_Create()
  {
     struct Foo* foo = malloc(sizeof(Foo));

     foo->p = malloc(sizeof(FooPrivate));

     foo->x = 0;
     foo->y = 0;
     foo->p->z = 0;

     return foo;
  }

  void Foo_DoWhatever(struct Foo* foo) 
  {
      foo->p->z = 4; /* Can access "private" parts of foo */
  }

在程序中:

  #include "foo.h"

  int main()
  {
      struct Foo* foo = Foo_Create();

      foo->x = 100; /* Can access "public" parts of foo */
      foo->p->z = 20; /* Error! FooPrivate is not fully declared here! */

      Foo_DoWhatever(foo); /* Can call "member" function */

      return 0;
  }

请注意需要使用“构造函数”来为私有(private)数据分配内存。显然,您需要将其与特殊的“析构函数”配对,以便正确释放私有(private)数据。

或者,或者,如果您希望您的结构没有任何公共(public)字段,您可以使整个结构不透明,并且只让 header 类似于

  struct Foo;

  extern struct Foo* Foo_Create(); /* "constructor" */

  extern void Foo_DoWhatever(struct Foo* foo); /* "member function" */

有了 foo.c 中 struct Foo 的实际定义,以及可用于您希望提供直接访问的任何属性的 getter 和 setter 函数。

关于c - 将结构划分为私有(private)和公共(public)部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3824329/

相关文章:

c - 如何在 libcurl 中使用 CURLINFO_PRIVATE 访问结构?

objective-c - 类别访问主类的私有(private)方法 - Objective C

c - 这段C代码有什么问题? (未按预期工作)

c - 此解决方案中的信号量使用是否正确?

ios - 当用作函数中的参数时,结构值类型前面需要关键字 var

javascript - 从 JavaScript 中的私有(private)方法访问成员变量

ruby - 子类中是否可以访问 Ruby 私有(private)方法?

c - memcpy 中的 EXC_BAD 访问

c - 检测日志文件已在 POSIX 系统上被删除或截断?

c - 使用函数调用来实现堆栈