Implementing polymorphic behaviour

Discussion in 'C Programming' started by Laurent Deniau, Oct 24, 2007.

  1. On 24 oct, 12:30, Daniel Kraft <> wrote:
    > Hi,
    >
    > I usually program in C++, but for a special project I do have to code in
    > C (because it may be ported to embedded-like platforms where no C++
    > compiler exists).
    >
    > I do want to realize some kind of polymorphic behaviour, like this:
    >
    > I have some abstract base "class" Base, that is, a struct containing a
    > vtable of function-pointers and possibly some common fields (but at the
    > moment, there aren't any such fields, if this does make a difference).
    >
    > Then I need some concrete sub-classes, say A and B, implementing those
    > virtual methods and both having their own number of fields; I do not
    > need a more complicated class-hirarchy, only these two levels.
    >
    > My main problem is how to structure the data combining common fields
    > (vtable) and the fields special to A or B.


    you may be interested by OOC-S:

    http://cern.ch/laurent.deniau/oopc.html#OOC-S

    which already does this with a particular attention to encapsulation
    (ADT).

    a+, ld
     
    Laurent Deniau, Oct 24, 2007
    #1
    1. Advertising

  2. Laurent Deniau

    Daniel Kraft Guest

    Hi,

    I usually program in C++, but for a special project I do have to code in
    C (because it may be ported to embedded-like platforms where no C++
    compiler exists).

    I do want to realize some kind of polymorphic behaviour, like this:

    I have some abstract base "class" Base, that is, a struct containing a
    vtable of function-pointers and possibly some common fields (but at the
    moment, there aren't any such fields, if this does make a difference).

    Then I need some concrete sub-classes, say A and B, implementing those
    virtual methods and both having their own number of fields; I do not
    need a more complicated class-hirarchy, only these two levels.

    My main problem is how to structure the data combining common fields
    (vtable) and the fields special to A or B. I did come up with two
    methods, and would like to know what you suggest to be the better one
    (or any other suggestions).

    Method 1
    ========

    typedef struct
    {
    void (*method)(void* me);
    } vtable;

    /* This is the base class, holding the common fields and a pointer to
    the sub-class' data */
    typedef struct
    {
    vtable* methods;
    void* subclass;
    } Base;

    typedef struct
    {
    int field;
    } A;

    typedef struct
    {
    double field;
    } B;

    In the specific implementation of method, I'd cast the void* to A*/B* to
    access the fields; however, this would mean that each object consisted
    of *two* dynamically allocated blocks of memory. This additional
    overhead is surely not a real performance problem in my case, but it
    seems somewhat unneccessary complicated to me.

    And it would require some more tricks (or at least an additional
    argument to each virtual method) to have access to the vtable and
    possible common fields.

    Method 2
    ========

    struct Base;

    typedef struct
    {
    void (*method)(struct Base* me);
    } vtable;

    typedef struct
    {
    vtable* methods;
    } Base;

    typedef struct
    {
    Base base;
    int field;
    } A;

    typedef struct
    {
    Base base;
    float field;
    } B;

    Here, one would only allocate a single block of memory for A or B,
    respectively, so that the Base instance is carried right with each
    subclass. I do like this more in general; however, in each virtual
    method, I'd have to case struct Base* me to A* me or B* me--this is the
    point I'm unsure about.

    Does the standard allow this, i.e., can I store an A* in a struct Base*
    variable, and recast it back without any problems? Or might those two
    pointers be different?

    Could I use void* as argument in the second case, too, because void* is
    required to hold *any* pointer?

    I'm sure there is some elegant and portable solution... Thanks for your
    advice!

    Daniel

    --
    Got two Dear-Daniel-Instant Messages
    by MSN, associate ICQ with stress--so
    please use good, old E-MAIL!
     
    Daniel Kraft, Oct 24, 2007
    #2
    1. Advertising

  3. Laurent Deniau

    Guest

    On Oct 24, 3:30 am, Daniel Kraft <> wrote:
    > Hi,
    >
    > I usually program in C++, but for a special project I do have to code in
    > C (because it may be ported to embedded-like platforms where no C++
    > compiler exists).
    >
    > I do want to realize some kind of polymorphic behaviour, like this:
    >
    > I have some abstract base "class" Base, that is, a struct containing a
    > vtable of function-pointers and possibly some common fields (but at the
    > moment, there aren't any such fields, if this does make a difference).
    >
    > Then I need some concrete sub-classes, say A and B, implementing those
    > virtual methods and both having their own number of fields; I do not
    > need a more complicated class-hirarchy, only these two levels.
    >
    > My main problem is how to structure the data combining common fields
    > (vtable) and the fields special to A or B. I did come up with two
    > methods, and would like to know what you suggest to be the better one
    > (or any other suggestions).
    >
    > Method 1
    > ========
    >
    > typedef struct
    > {
    > void (*method)(void* me);
    >
    > } vtable;
    >
    > /* This is the base class, holding the common fields and a pointer to
    > the sub-class' data */
    > typedef struct
    > {
    > vtable* methods;
    > void* subclass;
    >
    > } Base;
    >
    > typedef struct
    > {
    > int field;
    >
    > } A;
    >
    > typedef struct
    > {
    > double field;
    >
    > } B;
    >
    > In the specific implementation of method, I'd cast the void* to A*/B* to
    > access the fields; however, this would mean that each object consisted
    > of *two* dynamically allocated blocks of memory. This additional
    > overhead is surely not a real performance problem in my case, but it
    > seems somewhat unneccessary complicated to me.
    >
    > And it would require some more tricks (or at least an additional
    > argument to each virtual method) to have access to the vtable and
    > possible common fields.
    >
    > Method 2
    > ========
    >
    > struct Base;
    >
    > typedef struct
    > {
    > void (*method)(struct Base* me);
    >
    > } vtable;
    >
    > typedef struct
    > {
    > vtable* methods;
    >
    > } Base;
    >
    > typedef struct
    > {
    > Base base;
    > int field;
    >
    > } A;
    >
    > typedef struct
    > {
    > Base base;
    > float field;
    >
    > } B;
    >
    > Here, one would only allocate a single block of memory for A or B,
    > respectively, so that the Base instance is carried right with each
    > subclass. I do like this more in general; however, in each virtual
    > method, I'd have to case struct Base* me to A* me or B* me--this is the
    > point I'm unsure about.
    >
    > Does the standard allow this, i.e., can I store an A* in a struct Base*
    > variable, and recast it back without any problems? Or might those two
    > pointers be different?
    >
    > Could I use void* as argument in the second case, too, because void* is
    > required to hold *any* pointer?
    >
    > I'm sure there is some elegant and portable solution... Thanks for your
    > advice!
    >
    > Daniel
    >
    > --
    > Got two Dear-Daniel-Instant Messages
    > by MSN, associate ICQ with stress--so
    > please use good, old E-MAIL!


    Look at how Motif widgets work.

    For example, a Core widget is defined with these structs:
    /*BEGIN*/
    typedef struct _corePart {
    /* instance variables */
    } CorePart;

    typedef struct _WidgetRec {
    CorePart core;
    } WidgetRec, CoreRec;

    typedef struct _CoreClassPart {
    /* class variables and method pointers */
    } CoreClassPart;

    typedef struct _WidgetClassRec {
    CoreClassPart core_class;
    } WidgetClassrec, CoreClassRec;

    extern WidgetClassRec widgetClassRec;
    /*END*/

    Then one can make a subclass MyWidget:
    /*BEGIN*/

    typedef struct MyWidgetPart {
    /* instance variables the subclass */
    } MyWidgetPart;

    typedef struct MyWidgetRec {
    CorePart core;
    MyWidgetPart my_widget;
    } MyWidgetRec;

    typedef struct MyWidgetClassPart {
    /* class variables and methods for the subclass */
    } MyWidgetClassPart;

    typedef struct MyWidgetClassRec {
    CoreClassPart core_class;
    MyWidgetClassPart my_widget_class;
    } MyWidgetClassRec;
    extern MyWidgetClassRec myWidgetClassRec;
    /*END*/

    To subclass this subclass, just add more items in the structs.
    For example, the class rec for a subclass of MyWidget
    (call it MySubWidget) would be:


    typedef struct MySubWidgetClassRec {
    CoreClassPart core_class;
    MyWidgetClassPart my_widget_class;
    MySubWidgetClassPart my_sub_widget_class;
    } MySubWidgetClassRec;


    Refer to the Motif source code for how polymorphisms work
    (by changing the function pointers in the .c file's
    myWidgetClass reference).

    --
    Fred L. Kleinschmidt
     
    , Oct 24, 2007
    #3
  4. Laurent Deniau

    Daniel Kraft Guest

    >> I usually program in C++, but for a special project I do have to code in
    >> C (because it may be ported to embedded-like platforms where no C++
    >> compiler exists).
    >>
    >> I do want to realize some kind of polymorphic behaviour, like this:
    >>
    >> I have some abstract base "class" Base, that is, a struct containing a
    >> vtable of function-pointers and possibly some common fields (but at the
    >> moment, there aren't any such fields, if this does make a difference).
    >>
    >> Then I need some concrete sub-classes, say A and B, implementing those
    >> virtual methods and both having their own number of fields; I do not
    >> need a more complicated class-hirarchy, only these two levels.
    >>
    >> My main problem is how to structure the data combining common fields
    >> (vtable) and the fields special to A or B.

    >
    > you may be interested by OOC-S:
    >
    > http://cern.ch/laurent.deniau/oopc.html#OOC-S
    >
    > which already does this with a particular attention to encapsulation
    > (ADT).


    Hm, thanks for this link. However, it seems although this is already
    named "simplified", that this should model Java's object hierarchy
    (including java.lang.Object's interface) in C, which for my own purpose
    only seems to be unneccessary bloat.

    I don't really need all those object-methods, nor real "interface
    semantics" or even reference-counting. So I think I will stick to
    implementing my own, "more simplified" object system ;)

    Thanks,
    Daniel

    --
    Got two Dear-Daniel-Instant Messages
    by MSN, associate ICQ with stress--so
    please use good, old E-MAIL!
     
    Daniel Kraft, Oct 24, 2007
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Manco

    can webmethods be polymorphic?

    Manco, Feb 3, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    340
    Lionel LASKE
    Feb 3, 2005
  2. Thomas Britton

    polymorphic behaviour from class constant

    Thomas Britton, May 1, 2004, in forum: Java
    Replies:
    1
    Views:
    346
    Chris Uppal
    May 2, 2004
  3. Khanh  Le

    polymorphic question

    Khanh Le, May 2, 2004, in forum: Java
    Replies:
    3
    Views:
    411
    Tim Van Wassenhove
    May 2, 2004
  4. -electric.com

    SOAP: Creating a polymorphic Data Type

    -electric.com, Feb 17, 2005, in forum: Java
    Replies:
    0
    Views:
    407
    -electric.com
    Feb 17, 2005
  5. Alan Woodland
    Replies:
    12
    Views:
    562
    Marco Manfredini
    Nov 22, 2007
Loading...

Share This Page