You can also implement data hiding in C. Instead of making a variable "global," use static to prevent it from being exported to the linker and then write access functions:
static int foo;
int foo_get(void)
{
return foo;
}
void foo_set(int f)
{
foo=f;
}
Of course, you'll probably want some more code that performs access checks before returning or changing foo.
This differs from a private class variable in C++, though, in the sense that there's only one copy of foo shared by the entire program.
To get around this problem and retain the data hiding, you can create "opaque" types, effectively making all members of a struct private.
foo.h
-----
#ifndef FOO_H
#define FOO_H
/* Incomplete type, user can create
* pointers to struct foo, but its
* innards aren't exposed */
struct foo;
typedef struct foo foo_t;
/* Constructor */
extern foo_t *
foo_alloc(void);
/* Destructor */
extern void
foo_free(foo_t *);
/* Functions that operate on foo objects */
extern void
foo_print(const foo_t *);
extern int
foo_get_i(const foo_t *);
extern void
foo_set_i(foo_t *,int);
extern char
foo_get_c(const foo_t *);
extern void
foo_set_c(foo_t *,char);
extern double
foo_get_d(const foo_t *);
extern void
foo_set_d(foo_t *,double);
#endif
foo.c
-----
#include <stdio.h>
#include <stdlib.h>
#include "foo.h"
/* struct foo is defined here, making
* its definition unavailable to
* the user directly. */
struct foo {
int i;
char c;
double d;
};
/* Print a foo object */
void
foo_print(const foo_t *foo)
{
printf("%d; %c; %f\n",foo->i,foo->c,foo->d);
}
/* Accessor methods */
int
foo_get_i(const foo_t *foo)
{
return foo->i;
}
void
foo_set_i(foo_t *foo,int i)
{
foo->i=i;
}
char
foo_get_c(const foo_t *foo)
{
return foo->c;
}
void
foo_set_c(foo_t *foo,char c)
{
foo->c=c;
}
double
foo_get_d(const foo_t *foo)
{
return foo->d;
}
void
foo_set_d(foo_t *foo,double d)
{
foo->d=d;
}
/* Constructor */
foo_t *
foo_alloc(void)
{
foo_t *foo=malloc(sizeof *foo);
if (foo) {
foo->i=0;
foo->c=0;
foo->d=0.0;
}
return foo;
}
void
foo_free(foo_t *foo)
{
free(foo);
}
foo_test.c
----------
/* Test suite */
#include "foo.h"
int main(void)
{
foo_t *foo=foo_alloc();
if (foo) {
foo_set_i(foo,10);
foo_set_c(foo,'A');
foo_set_d(foo,8.88);
foo_print(foo);
foo_free(foo);
}
return 0;
}
The advantage is that the user must use the accessor functions to access or change members of the struct. The disadvantage is that the user can only create pointers to struct foo, because it is an incomplete type.
Russ
bobbitts@hotmail.com