Here is what I got ..
typedef struct SysInfo_P
{
int some_P_int;
char some_P_char[10];
...
} SysInfo_P;
typedef struct SysInfo_S
{
int some_S_int;
char some_S_char[10];
...
} SysInfo_S;
typedef struct Device
{
struct SomeData *data;
void *sysInfo;
...
} Device;
The idea is to have a base class Device, and cast its void
pointer to the appropriate SysInfo_x
class during allocation. I use void
pointers all the time to provide versatility to common functions, but I can't seem to wrap my head around this ... perhaps it cannot be done.
Here is my futile attempt at casting it .. in my allocator.
self->sysInfo = (SysInfo_S *)malloc(sizeof(*self->properties->sysInfo));
memset(self->sysInfo, 0, sizeof(*self->properties->sysInfo));
So since there is so much good info in this thread, i thought I should clarify the question, and the what I was trying to Achieve and why.This require more context...
The project is and IOT library written in C. Since it must support many types of devices, all just a little bit different, naturally an OOP approach was best suited.
So at first i used a quick and dirty solution,include pointers to both types, then allocate only the necessary type during constructing. This works great if you don"t mind wading through extra pointers to nowhere in your code editor when including library .. so really, the question wasn't so much about how to do it, but more so, about how to do it in a clean way. The first answer i accepted was more-less just a better (more memory efficient way) of doing what i was already doing. I still ended up with the same issue, all device, methods..sysinfo .etc pollute device/Object specific properties and methods.
the key to my solution was the second answer i accepted, including the base class as the first member of the derived classes.
As mentioned, the library must interact with many device types, so my solution was to give each type it own class, then use the base class to access the child from with in functions, since the devices are all very closely related this works very well and eliminated any need for void pointers.
here was the solution to my problem ...
typedef struct SysInfo_P
{
Device base;
int some_P_int;
char some_P_char[10];
...
} SysInfo_P;
typedef struct SysInfo_S
{
Device base;
int some_S_int;
char some_S_char[10];
...
} SysInfo_S;
typedef struct Device_S
{
Device base;
SysInfo_S *sysinfo;
} Device_S;
typedef struct Device_P
{
Device base;
SysInfo_P *sysinfo;
} Device_P;
typedef struct Device
{
uint8_t type;
uint8_t device_index;
uint8_t type_index;
} Device;
This way, i can just pass the base class around, and used the type and type_index to access the child directly, from within. Perfect!!
hopefully t this thread saves someone a great deal of time .. i spent many hours looking for the right solution. Because of the answer and few key tips from @Jason this library is done and exceeds all criteria. Thank again to everyone and big thanks to S.O fora site full of such a great information and knowledgeable members. Cheers