470,816 Members | 1,271 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,816 developers. It's quick & easy.

Implementing polymorphic behaviour

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!
Oct 24 '07 #1
3 1440
On 24 oct, 12:30, Daniel Kraft <d...@domob.euwrote:
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

Oct 24 '07 #2
>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!
Oct 24 '07 #3
On Oct 24, 3:30 am, Daniel Kraft <d...@domob.euwrote:
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 '07 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

9 posts views Thread by Bernard | last post: by
20 posts views Thread by verec | last post: by
7 posts views Thread by James Fortune | last post: by
12 posts views Thread by Bob | last post: by
5 posts views Thread by FefeOxy | last post: by
13 posts views Thread by Tristan Wibberley | last post: by
reply views Thread by mihailmihai484 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.