473,383 Members | 1,733 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,383 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 1617
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
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

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.