How to best have c++ class-style structs?

B

bahadir.balban

Hi,

In my programming I do something like,

struct my_struct {
int data1;
int data1;
static void (* const my_privatefunc1) (my_struct * this)
static void (* const my_privatefunc2) (my_struct * this)
}
// function definitions
static void my_privatefunc1(mystruct * this) { }
static void my_privatefunc2(mystruct * this) { }

And on initialisation I do:

struct my_struct x = {
0,
0,
my_privatefunc1,
my_privatefunc2
};

if I had an init function for this, I would best have one that
allocated, initialised and returned a new object from heap, i.e.
my_struct * xp = x_allocator_and_initialisor();

or if I want my object on the stack, I could have a loose init function
and a struct on stack, i.e.
my_struct x; x_initialisor(&x);

But, whatif I wanted a statically allocated object, yet initialised,
and client involved in neither setting values explicitly, nor
associating it with such an init function. i.e. if I could do;

my_struct x; x.init(); that would be nice, because I dont want to have
the loose practices above. But would it be possible to associate init()
with x like this, in the first place?

Cheers,
Bahadir
 
J

jacob navia

Hi,

In my programming I do something like,

struct my_struct {
int data1;
int data1;
static void (* const my_privatefunc1) (my_struct * this)
static void (* const my_privatefunc2) (my_struct * this)
}
// function definitions
static void my_privatefunc1(mystruct * this) { }
static void my_privatefunc2(mystruct * this) { }

And on initialisation I do:

struct my_struct x = {
0,
0,
my_privatefunc1,
my_privatefunc2
};

if I had an init function for this, I would best have one that
allocated, initialised and returned a new object from heap, i.e.
my_struct * xp = x_allocator_and_initialisor();

or if I want my object on the stack, I could have a loose init function
and a struct on stack, i.e.
my_struct x; x_initialisor(&x);

But, whatif I wanted a statically allocated object, yet initialised,
and client involved in neither setting values explicitly, nor
associating it with such an init function. i.e. if I could do;

my_struct x; x.init(); that would be nice, because I dont want to have
the loose practices above. But would it be possible to associate init()
with x like this, in the first place?

Cheers,
Bahadir

There is no way in C to call an initialization function before
the main() function runs.

One work-around is to call an initialiaztion function as the first
procedure called by main(). That function would call all other
initializations necessary for all objects you build.

Another is to assign to your objects statically their value:

static my_struct myobject = {
0, 25, myfn1,myfn2};

and be done with it :)

jacob
 
D

DHOLLINGSWORTH2

You cannot Statically allocate a dynamically allocated resource. That is
you can Statically or Dynamically allocate, not both.

Some compilers do allow for code execution before main. I'm not sure if it
is a standard. ( one of these days I'll download it.)

It should be found in your documentation about the same place as atexit();
 
E

E. Robert Tisdale

In my programming I do something like,

struct my_struct {
int data1;
int data1;
static void (*const my_privatefunc1) (my_struct * this)
static void (*const my_privatefunc2) (my_struct * this)
}
// function definitions
static void my_privatefunc1(mystruct * this) { }
static void my_privatefunc2(mystruct * this) { }

// And on initialisation I do:

struct my_struct x = {
0,
0,
my_privatefunc1,
my_privatefunc2
};

This is completely bogus:
> gcc -Wall -std=c99 -pedantic -S my_struct.c
my_struct.c:4: error: parse error before "static"
my_struct.c:4: warning: no semicolon at end of struct or union
my_struct.c:8: error: parse error before '*' token
my_struct.c:9: error: parse error before '*' token
my_struct.c:11: error: parse error before "on"
my_struct.c:18: warning: ISO C does not allow extra `;' \
outside of a function
my_struct.c:8: warning: 'my_privatefunc1' defined but not used
my_struct.c:9: warning: 'my_privatefunc2' defined but not used
If I had an init function for this,
I would best have one that
allocated, initialised and returned a new object from heap, i.e.

my_struct * xp = x_allocator_and_initialisor();

or, if I want my object on the stack,
I could have a loose init function and a struct on stack, i.e.

my_struct x; x_initialisor(&x);

But, whatif I wanted a statically allocated object, yet initialised,
and client involved in neither setting values explicitly, nor
associating it with such an init function. i.e. if I could do;

my_struct x; x.init();

that would be nice, because I don't want to have the loose practices above.
But would it be possible to associate init() with x like this, in the first place?

Try this:
> cat my_struct.h
#ifndef GUARD_MY_STRUCT_H
#define GUARD_MY_STRUCT_H 1

#include <stdio.h>

typedef struct my_struct {
const
void* const pVFT;
int data1;
int data2;
} my_struct;

// virtual functions
void my_struct_func1(const my_struct* p);
void my_struct_func2(const my_struct* p);

// constructors
my_struct my_struct_create(int d1, int d2);
void my_struct_destroy(const my_struct* p);

#endif//GUARD_MY_STRUCT_H
> cat my_struct.c
#include "my_struct.h"

// function definitions
static void my_privatefunc1(const my_struct* p) {
fprintf(stderr, "my_privatefunc1(const my_struct*): "
"data1 = %d\n", p->data1);
}
static void my_privatefunc2(const my_struct* p) {
fprintf(stderr, "my_privatefunc2(const my_struct*): "
"data2 = %d\n", p->data2);
}

typedef struct my_struct_virtualFunctionTable_t {
void (* const my_privatefunc1)(const struct my_struct*);
void (* const my_privatefunc2)(const struct my_struct*);
} my_struct_virtualFunctionTable_t;

my_struct_virtualFunctionTable_t my_struct_VFT = {
my_privatefunc1,
my_privatefunc2
};

// virtual functions
void my_struct_func1(const my_struct* p) {
((my_struct_virtualFunctionTable_t*)(p->pVFT))
->my_privatefunc1(p);
}
void my_struct_func2(const my_struct* p) {
((my_struct_virtualFunctionTable_t*)(p->pVFT))
->my_privatefunc2(p);
}

// constructors
my_struct my_struct_create(int d1, int d2) {
my_struct x = { (void*)(&my_struct_VFT), d1, d2 };
return x;
}
void my_struct_destroy(const my_struct* p) { }
> cat main.c
#include "my_struct.h"

int main(void) {
const
my_struct t = my_struct_create(13, 42);
my_struct_func1(&t);
my_struct_func2(&t);
my_struct_destroy(&t);
return 0;
}
> gcc -Wall -std=c99 -pedantic -o main main.c my_struct.c
> ./main
my_privatefunc1(const my_struct*): data1 = 13
my_privatefunc2(const my_struct*): data2 = 42
 
B

bahadir.balban

while not _completely bogus_ yes, there are a few typos, but
functionally the method is correct. Here's a compilable version:

struct my_struct {
int dataA;
int dataB;
void (* const my_privatefunc1) (struct my_struct *);
void (* const my_privatefunc2) (struct my_struct *);

};
static void my_privatefunc1(struct my_struct * this) { }
static void my_privatefunc2(struct my_struct * this) { }


int main (int argc, char * argv[])
{
struct my_struct x = {
0,
0,
my_privatefunc1,
my_privatefunc2
};
}

I think your method is a useful imitation of c++ should one need
virtual functions. But your constructor creates the object on the stack
and returns it. So won't you have problems with that?

Bahadir
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top