Struct Inheritance in C
Solution 1:
The closest you can get is the fairly common idiom:
typedef struct
{
// base members
} Base;
typedef struct
{
Base base;
// derived members
} Derived;
As Derived
starts with a copy of Base
, you can do this:
Base *b = (Base *)d;
Where d
is an instance of Derived
. So they are kind of polymorphic. But having virtual methods is another challenge - to do that, you'd need to have the equivalent of a vtable pointer in Base
, containing function pointers to functions that accept Base
as their first argument (which you could name this
).
By which point, you may as well use C++!
Solution 2:
C has no explicit concept of inheritance, unlike C++. However, you can reuse a structure in another structure:
typedef struct {
char name[NAMESIZE];
char sex;
} Person;
typedef struct {
Person person;
char job[JOBSIZE];
} Employee;
typedef struct {
Person person;
char booktitle[TITLESIZE];
} LiteraryCharacter;
Solution 3:
I like and used the idea of Typesafe inheritance in C.
For example:
struct Animal
{
int weight;
};
struct Felidae
{
union {
struct Animal animal;
} base;
int furLength;
};
struct Leopard
{
union {
struct Animal animal;
struct Felidae felidae;
} base;
int dotCounter;
};
Usage:
struct Leopard leopard;
leopard.base.animal.weight = 44;
leopard.base.felidae.furLength = 2;
leopard.dotCounter = 99;
Solution 4:
If your compiler supports anonymous structs, you can do this:
typedef struct Base
{
// base members
} Base_t;
typedef struct
{
struct Base; //anonymous struct
// derived members
} Derived_t;
This way, base stuct members can be acessed directly, which is nicer.
Solution 5:
If you want to use some gcc magic (that I would assume would work with Microsoft's C compiler) you can do something like:
struct A
{
int member1;
};
struct B
{
struct A;
int member2;
}
With gcc you can compile this with -fms-extensions (Allows for unnamed struct members like Microsofts compiler does). This is similar to the solution given by Daniel Earwicker except that it allows you to access memeber1 on a struct B instance. i.e B.member1 instead of B.A.member1.
This is probably not the most portable approach and will not work if using a C++ compiler (different language semantics mean that it is redeclaring/defining struct A instead of instantiating it).
If however you live in the gcc/C land only it will work and do exactly what you want.