473,224 Members | 1,953 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,224 software developers and data experts.

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 1609
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: Dave | last post by:
What is the expected output of this program and why??? #include <iostream> using namespace std; class base {
9
by: Bernard | last post by:
Hi All, I am not sure if I should be asking this question on clc or clc++. Let me try on both. I hope that this is not too trivial for the brilliant minds over here. I know that OOP questions...
20
by: verec | last post by:
One problem I've come accross in designing a specific version of auto_ptr is that I have to disntiguish between "polymorphic" arguments and "plain" ones, because the template has to, internally,...
7
by: James Fortune | last post by:
In response to different users or situations (data context) I transform the appearance and characteristics of Access Forms through code. This seems to fit in with the idea of polymorphism. Do...
12
by: Bob | last post by:
Hi, 'Shadowed' properties are not polymorphic. (See thread 'Inheritance and late binding') They should be. Problem: Base class has read only property 'X'. Derived class must have read / write...
5
by: FefeOxy | last post by:
Hi, > I'm having a debug assertion error within the file dbgdel.cpp with the expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) I traced the origin of the error and it happened as I tried to...
11
by: Angus | last post by:
I am developing a server which receives a range of different messages. There are about 12 different message types so I thought that a good idea would be to devise a class for each message type....
13
by: Tristan Wibberley | last post by:
Hi I've got implementing overloaded operator new and delete pretty much down. Just got to meet the alignment requirements of the class on which the operator is overloaded. But how does one...
11
by: Alan Woodland | last post by:
Hi, I'm fairly sure this is undefined behaviour, despite the fact that it compiles and 'runs' (prints "this doesn't exist") on all my platforms: #include <iostream> class foo { public:...
1
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
0
by: VivesProcSPL | last post by:
Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many English-like terms and syntax in an effort to make it easy to learn, particularly for...
0
by: jianzs | last post by:
Introduction Cloud-native applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from...
0
by: mar23 | last post by:
Here's the situation. I have a form called frmDiceInventory with subform called subfrmDice. The subform's control source is linked to a query called qryDiceInventory. I've been trying to pick up the...
2
by: jimatqsi | last post by:
The boss wants the word "CONFIDENTIAL" overlaying certain reports. He wants it large, slanted across the page, on every page, very light gray, outlined letters, not block letters. I thought Word Art...
0
by: stefan129 | last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multi-domain SSL certificates? Any recommendations on reliable providers or specific...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.