Re: "data hiding" prototype code




"sofeng" <sofengboe@xxxxxxxxx> wrote in message
news:1176396113.272470.33060@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
On Apr 11, 4:39 pm, "Jonas" <spamhereple...@xxxxxxxxx> wrote:
"sofeng" <sofeng...@xxxxxxxxx> wrote in message

news:1176328415.501183.20910@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Thank you for your reply. See my comments below.

On Apr 11, 1:18 pm, "bluejack" <bluuj...@xxxxxxxxx> wrote:
First of all, making the variables static at file scope doesn't really
achieve the goal of encapsulation, particularly when you publish the
struct definition in the header. Secondly, static variables at file
scope are not much better than globals: they're certainly not thread
safe, and you open yourself to other sorts of errors as well.

I'm not sure what you mean by "publish the struct definition in the
header". I only put the typedef in the header-- that doesn't publish
the struct definition, right?

In your header file, you have

typedef struct {
double data1;
double data2;
double data3;
} ALGORITHM_DATA;

Instead, separate the typedef and the struct definition into header and
implementation files:

/* foo.h */
typedef struct foo_st foo_t;

/* foo.c */
#include "foo.h"

struct foo_st {
int bar;
};

Now, struct foo_st will be undefined outside of foo.c, which is what you
want to achieve. Pointers to foo_t can be defined by users of foo, but
foo_t
objects cannot, leaving your code in charge of this and anything that has
to
do with foo_t internals.

--
Jonas

But struct foo_st is synonymous with foo_t so why does it matter that
it is available outside of foo.c? Don't we really care about the
actual variable definition (where the memory is allocated) of type
"struct foo_st" or "foo_t"? For example, for the definition of
foo_var, "foo_t foo_var", foo_var should not be made available outside
of foo.c.


<context>
"sofeng" <sofeng...@xxxxxxxxx> wrote
I'm trying to:
1.) "hide" data (variables declared as static at file scope) within a
file (algorithm.c)
2.) manipulate the data using an algorithm function (Algorithm())
3.) provide external access to the data using an "accessor" function
(GetAlgorithmData())
</context>

Inside foo.c, after the definition of struct foo_st, this will be a complete
type, instances of which can then be defined and its members manipulated.
Everywhere else, this will not be possible. This will "hide" your data. In
order to provide access to and ways to manipulate the data, consider the
following:

/* foo.h */
typedef struct foo_st foo_t;

foo_t * foo_create();
void foo_destroy(foo_t *foo);
void foo_set_bar(foo_t *foo, int bar);
int foo_get_bar(const foo_t *foo);
void foo_manipulate(foo_t* foo);


/* foo.c */
#include "foo.h"

struct foo_st {
int bar;
};

foo_t * foo_create()
{
return malloc (sizeof(foo_t));
}

void foo_destroy(foo_t *foo)
{
free(foo);
}

/* implementation of other functions declared in foo.h should follow...
*/

The user of your code will only include foo.h, and thus will never be able
to access the elements of struct foo_st directly (to them, it will be an
incomplete type, declared but not defined), nor be able to create objects of
type foo_t. The only way to do this will be to use the API you provide. The
_good thing_ here is that the user will not have to care about your
implementation of foo_t, you are free to change anything you please as long
as the API is kept intact.

If you want there to be only *one* foo_t object, as implied in point (3),
then you could declare a static variable in foo.c:

/* foo.h */
typedef struct foo_st foo_t;

foo_t * foo_get_instance();
void foo_manipulate(foo_t *foo);


/* foo.c */
#include "foo.h"

struct foo_st {
int bar;
};

static foo_t foo_instance;
static int is_initialized = 0;

foo_t * foo_get_instance()
{
if (!is_initialized) {
foo.bar = 0;
is_initialized = 1;
}
return &foo_instance;
}

/* implementation of other functions declared in foo.h should follow...
*/

Now, the only foo_t object in existence will be the one defined in foo.c,
since objects of the type cannot be defined anywhere else. This would be
akin to a singleton in the OO-paradigm.

--
Jonas


.



Relevant Pages

  • Re: Ive got a strange bug with Listbox.DataSource...
    ... > I have a WebService that contains the following struct definition. ... DisplayMember contains "ID" and ValueMember contains ""... ... but, once the last line of code> executes, the DisplayMember value gets replaced by "" and the only thing> appearing in the listbox is the type information of Record which is probably> caused by the fact the listbox calls .ToStringon each members of the> Array. ... is there a problem with using a> struct definition from a WebService? ...
    (microsoft.public.dotnet.languages.csharp)
  • Ive got a strange bug with Listbox.DataSource...
    ... I have a WebService that contains the following struct definition. ... DisplayMember contains "ID" and ValueMember contains ""... ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: [PATCH 13/15] perf_counter: provide generic callchain bits
    ... struct definition is not visible to userspace (it's in the #ifdef KERNEL ... header in the userspace bits. ... chain with 0ULL. ... This chain however will not change the struct, ...
    (Linux-Kernel)
  • Re: "data hiding" prototype code
    ... struct definition in the header. ... typedef struct foo_st foo_t; ...
    (comp.lang.c)
  • Re: null function pointer?
    ... >> The type is incomplete until the closing brace of the list ... > point of the code in your example in all declarations `struct foo' ... > declarations have the same scope and use the same struct tag). ... > type before and after the struct definition, ...
    (comp.lang.c)