Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Struct Inheritance in C

Tags:

c

structure

People also ask

Can struct be inherited in C?

No you cannot. C does not support the concept of inheritance.

Can we do inheritance in struct?

Yes. The inheritance is public by default.

Does C use inheritance?

No it doesnt. C is not an Object Oriented language. Inheritance is a property of OO languages.

Can you do inheritance with structs C++?

C++ Classes/Structures InheritanceClasses/structs can have inheritance relations. If a class/struct B inherits from a class/struct A , this means that B has as a parent A . We say that B is a derived class/struct from A , and A is the base class/struct.


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++!


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;

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;

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.


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.


You can do the above mentioned

typedef struct
{
    // base members

} Base;

typedef struct
{
    Base base;

    // derived members

} Derived;

But if you want to avoid pointer casting, you can use pointers to a union of Base and Derived.