I know that struct members can be hidden by using an incomplete
typedef in a .h file with the full declaration in the
implementation .c file which also contains a 'constructor' which
creates 'instances' on the heap and 'methods' which take a 'this'
pointer argument.
The problem for me with this approach is that the size of the type is
unknown outside the implementation .c file so the compiler can't
allocate space for static or local variables of that type.
Is there some way to achieve data hiding without using the heap, ie
static or local variables only ?
--
comp.lang.c.moderated - moderation address: cl...@plethora.net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
> Is there some way to achieve data hiding without using the heap, ie
> static or local variables only ?
The problem is not really data hiding. Pointers do that nicely,
regardless of where the objects are located. The problem with pointers
is rather that you need to have an object that they point to, and that
object must reside somewhere in memory. (-:
There is no problem creating objects on the stack, and using their
addresses in a second structure to hide their layout. The problem is
that you cannot create "constructors" this way that allocate objects of
an unknown type since then the lifetime of the object is bound to the
life-time of the function keeping the object on the stack, and this
problem doesn't go away by *not* using pointers. It becomes even more
visible without pointers, though. (-:
A question: Can you limit the number of objects you need? If so, I would
suggest to split the source into several modules, each responsible for
maintaining objects of one kind (that is, structures). If it is granted
that you need only at most N elements of type A, you could allocate
these objects statically in an array, and on construction just pass out
the next available object, keeping an indicator in the object whether it
is "free" or "used".
So long,
Thomas
I am finding it hard to see why you want to use OO for this kind of
program. I think it is the wrong paradigm for the job.
perhaps you can use the preprocessor.
in the header file do this.
#define FOO_PRIVATE_MEMBERS\
int x,y,z ;\
float u,v;\
char *w ;
#define FOO_PUBLIC_MEMBERS\
int a,b,c ; \
float d,e,f;
struct foo {
FOO_PUBLIC_MEMBERS
#ifdef SHOW_FOO_PRIVATE_MEMBERS
FOO_PRIVATE_MEMBERS
#else
char foo_opaque_data [
sizeof( struct{ FOO_PUBLIC_MEMBERS FOO_PRIVATE_MEMBERS } )
- sizeof( struct{ FOO_PUBLIC_MEMBERS } )
];
#endif
}
#undef FOO_PRIVATE_MEMBERS
#undef FOO_PUBLIC_MEMBERS
in the c file for the module define #SHOW_FOO_PRIVATE_MEMBERS before
@including the header file that defines struct foo;
I have looked for ways to simplify the above and founde several that
fall down where alignment or padding are involved.
why is this strategy required for a program of fewer than 1000 lines?
I was wrong. don't do that if you want portable code.
be aware that if the private members have stricter alignment
requirements that the public member the public version of the struct
may be created with the wrong alignment.
so this could work on an 8-bit microcontroller but fail miserably on a
wider one like m68k (where misaligned ints are a critical fail)
if your private data is not stricter aligned that the public part then
it should be safe.
Why am I attempting OO on such a small app ? Well, I guess 10 years
of Java and C# mean I think in objects. I only use C in hobby
microcontroller apps.
When I recently stumbled across the GTK+ GUI library I was fascinated
how they were doing OO in C. Made me wonder if I could make my
microcontroller apps more OO.
There's a sliding scale, from having conventions like
foo_create(struct foo*, ...) to monstrosities where everything is
malloc()ed memory, everything is typecast back and forth, and all
calls are by function pointers. I don't know where GTK+ is on the
scale.
IMHO, if you want more than what C plus some simple conventions can
give you, it's time to look for a C++ compiler. Even on a
microcontroller.
/Jorgen
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
I use a explict __private field to store the private members through
define one or more private type, which are anonymous structs when
included by others. And unique names are used through macros, those
are undefined at the end of head file to avoid name pollution as
above.
#define __Private \
struct { \
int x,y,z ;\
float u,v;\
char *w ; \
}
#ifdef FOO_MODULE
typedef __Private Private;
#else
# define Private __Private
#endif
struct foo {
/* Public members */
int a,b,c ;
float d,e,f;
/* Private member */
Private __private;
};
#undef __Private
#undef Private
in the c file for the module define #FOO_MODULE before @including the
header file that defines struct foo;