Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
360 views
in Technique[技术] by (71.8m points)

c - Partitioning struct into private and public sections?

In C++ and Java, data structures can have private, public and protected regions. I'd like to port this concept to a C language program I am writing.

Are there any idioms for implementing private or protected function pointers and data fields in a C struct? I know that C structs are public, I'm looking for an idiom to help hide some implementation details and force users to use the public interface.

Note: The language has been chosen by the shop, so I am stuck implementing Object Oriented concepts into C.

Thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

As you know, you cannot do this. However, there are idioms that will allow a similar effect.

C will allow you do do something similar to what is known as the "pimpl" idiom in object-oriented design. Your struct can have an opaque pointer to another forward-declared struct that acts as the struct's private data. Functions that operate on the struct, taking the place of member functions, can have the full definition for the private member, and can make use of it, while other parts of the code cannot. For example:

In a header, 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" */

In the implementation, 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 */
  }

In a program:

  #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;
  }

Note the need to use a "constructor" function in order to allocate memory for the private data. Obviously you would need to pair this with a special "destructor" function in order to deallocate the private data properly.

Or, alternatively, if you would like your struct to have no public fields whatsoever, you could make the entire struct opaque, and just have the header be something like

  struct Foo;

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

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

With the actual definition of struct Foo in foo.c, and getter and setter functions available for any properties you would like to provide direct access to.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...