Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hiding members in a C struct

I've been reading about OOP in C but I never liked how you can't have private data members like you can in C++. But then it came to my mind that you could create 2 structures. One is defined in the header file and the other is defined in the source file.

// ========================================= // in somestruct.h typedef struct {   int _public_member; } SomeStruct;  // ========================================= // in somestruct.c  #include "somestruct.h"  typedef struct {   int _public_member;   int _private_member; } SomeStructSource;  SomeStruct *SomeStruct_Create() {   SomeStructSource *p = (SomeStructSource *)malloc(sizeof(SomeStructSource));   p->_private_member = 42;   return (SomeStruct *)p; } 

From here you can just cast one structure to the other. Is this considered bad practice? Or is it done often?

like image 426
Marlon Avatar asked Apr 20 '10 01:04

Marlon


People also ask

Can C struct have private members?

Sometimes a question arose "Can a structure has private members?" The answer is "Yes! In C++, we can declare private members in the structure". So the important thing is that "we can declare a structure just like a class with private and public members".

Can struct members be private?

Yes structures can have private members, you just need to use the access specifier for the same. struct Mystruct { private: m_data; }; Only difference between structure and class are: access specifier defaults to private for class and public for struct.

Can we hide data in C?

There are two features C offers to help hide data. The first feature is that you can declare a pointer to a struct that hasn't yet been defined. This is used in the example to declare a typedef for the stack type that is a pointer to a stack object struct without declaring the stack object struct.


2 Answers

sizeof(SomeStruct) != sizeof(SomeStructSource). This will cause someone to find you and murder you someday.

like image 120
hobbs Avatar answered Sep 21 '22 11:09

hobbs


Personally, I'd more like this:

typedef struct {   int _public_member;   /*I know you wont listen, but don't ever touch this member.*/   int _private_member; } SomeStructSource; 

It's C after all, if people want to screw up, they should be allowed to - no need to hide stuff, except:

If what you need is to keep the ABI/API compatible, there's 2 approaches that's more common from what I've seen.

  • Don't give your clients access to the struct, give them an opaque handle (a void* with a pretty name), provide init/destroy and accessor functions for everything. This makes sure you can change the structure without even recompiling the clients if you're writing a library.

  • provide an opaque handle as part of your struct, which you can allocate however you like. This approach is even used in C++ to provide ABI compatibility.

e.g

 struct SomeStruct {   int member;   void* internals; //allocate this to your private struct  }; 
like image 24
nos Avatar answered Sep 20 '22 11:09

nos