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?
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".
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.
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.
sizeof(SomeStruct) != sizeof(SomeStructSource)
. This will cause someone to find you and murder you someday.
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 };
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With