Is there any workaround for making a structure member somehow 'private' in C?

给你一囗甜甜゛ 提交于 2019-11-30 00:30:44

The usual techique is this:

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

Foo *foo_create(...);

void foo_bark(Foo* foo, double loudness);

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

You can partially hide data members by defining Foo in the header and FooPrivate in the .c file thus:

struct FooPrivate {
  Foo public_stuff;
  int private_var;
}

But then your implementation has to cast back and forth between Foo and FooPrivate, which I find to be a royal PITA, and is a maintenance burden if you change your mind later and want to make something private. Unless you want suck every last CPU cycle out of the code, just use accessor functions.

Marcelo Cantos has already given you the answer. For more detailed information, you should look at how FILE structure is effectively hidden in most of the uderlying libraries.

You would have noticed that the FILE structure in itself is never available to the user, only the interfaces and an Opaque FILE * is available to us.

Basically the idea is to rename the variables of the struct with something like a hash and write functions (that would sort of mimmic methods in OO languages) to access them. Ideally you should have function pointers to those functions in your struct so you don't have to call an external function and pass it hte struct who's members you wish to add. However function pointer syntax is not known to be the prettiest. A simple example that may clarify what was said before by 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;
}

I agree with Marcelo Cantos, but also suggest simply adding a pointer inside the "public" structure, which points to the "private" contents, i.e:

/* 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;
};

This approach is kind of like the "pimpl" ideom. The simplest approach by far is to do what Marcelo Cantos suggested.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!