473,396 Members | 1,804 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,396 software developers and data experts.

Constructing Class in C

A simple method of simulating a class, such as C++ or UML class, in C would
be using the struct construct. Similarly, we use C functions to simulate a
methods; e.g., rv method_a (&struct, parm_list); Other methods would be
fundamentally similar to this approach.

Are there any other approaches that would offer better maintainability and
readability? Do you have a better way of accurately simulating OO
visibility, inheritance, polymorphism, constructors, and destructors in C?

Hyoung
Nov 13 '05 #1
7 2460
Hyoung Lee wrote:
A simple method of simulating a class, such as C++ or UML class,
in C would be using the struct construct.
Similarly, we use C functions to simulate a methods;
e.g., rv method_a (&struct, parm_list);
Other methods would be fundamentally similar to this approach.
Are there any other approaches that would offer better maintainability and
readability? Do you have a better way of accurately simulating OO
visibility, inheritance, polymorphism, constructors, and destructors in C?


$ cat Point.h
#ifndef _Point_h
#define _Point_h 1

typedef struct {
/* representation */
double X;
double Y;
} Point;
/* functions */
double
xPoint(const Point *p);
double
yPoint(const Point *p);
/* constructors */
Point
createDefaultPoint(void);
Point
createExplicitPoint(double x, double y);
/* destructor */
void
destroyPoint(Point* p);

#endif /* _Point_h */

$ cat Point.c
/* gcc -I. -O2 -c Point.c
*/
#include<Point.h>

/* functions */
double
xPoint(const Point *p) {
return p->X; }
double
yPoint(const Point *p) {
return p->Y; }
/* constructors */
Point
createDefaultPoint(void) {
Point p;
p.X = 0.0;
p.Y = 0.0;
return p; }
Point
createExplicitPoint(double x, double y) {
Point p;
p.X = x;
p.Y = y;
return p;
}
/* destructor */
void
destroyPoint(Point* p) { }

$ cat Color.h
#ifndef _Color_h
#define _Color_h 1
typedef struct {
unsigned char R; /* red */
unsigned char G; /* green */
unsigned char B; /* blue */
} Color;
/* functions */
unsigned int
redColor(const Color *c);
unsigned int
greenColor(const Color *c);
unsigned int
blueColor(const Color *c);
/* constructors */
Color
createDefaultColor(void);
Color
createExplicitColor(
unsigned int r,
unsigned int g,
unsigned int b);
/* destructor */
void
destroyColor(Color *c);

#endif /* _Color_h */

$ cat Color.c
/* gcc -I. -O2 -c Color.c
*/
#include<Color.h>

/* functions */
unsigned int
redColor(const Color *c) {
return c->R; }
unsigned int
greenColor(const Color *c) {
return c->G; }
unsigned int
blueColor(const Color *c) {
return c->B; }
/* constructors */
Color
createDefaultColor(void) {
Color c;
c.R = 0;
c.G = 0;
c.B = 0;
return c; }
Color
createExplicitColor(
unsigned int r,
unsigned int g,
unsigned int b) {
Color c;
c.R = r;
c.G = g;
c.B = b;
return c; }
/* destructor */
void
destroyColor(Color *c) { }

$ cat Shape.h
#ifndef _Shape_h
#define _Shape_h 1

#include<Point.h>
#include<Color.h>

typedef void* virtual_t;
typedef struct {
Point P; /* first public base class */
Color C; /* second public base class */
virtual_t* V; /* virtual function table */
} Shape;
/* functions */
Point*
pointShape(Shape* s);
Color*
colorShape(Shape* s);
void
drawShape(const Shape *s);
void
drawGeneralShape(const Shape *s);
double
areaShape(const Shape *s);
double
areaGeneralShape(const Shape *s);
/* constructors */
Shape
createDefaultShape(void);
Shape
createExplicitShape(
const Point *p,
const Color *c);
/* destructor */
void
destroyShape(Shape *s);

#endif /* _Shape_h */

$ cat Shape.c
/* gcc -I. -O2 -c Shape.c
*/
#include<stdio.h>
#include<Shape.h>

typedef void (*drawShape_t)(const Shape *);
typedef double (*areaShape_t)(const Shape *);
/* functions */
Point*
pointShape(Shape* s) {
return &(s->P); }
Color*
colorShape(Shape* s) {
return &(s->C); }
void
drawGeneralShape(const Shape *s) {
fprintf(stderr, "drawShape(const Shape *s)\n");
fflush(stderr); }
double
areaGeneralShape(const Shape *s) {
fprintf(stderr, "areaShape(const Shape *s)\n");
fflush(stderr);
return 0.0; }
static virtual_t
vtableShape[] = {(virtual_t)drawGeneralShape,
(virtual_t)areaGeneralShape};
void
drawShape(const Shape *s) {
((drawShape_t)(s->V[0]))(s); }
double
areaShape(const Shape *s) {
return ((areaShape_t)(s->V[1]))(s); }
/* constructors */
Shape
createDefaultShape(void) {
Shape S;
S.P = createDefaultPoint();
S.C = createDefaultColor();
S.V = vtableShape;
return S; }
Shape
createExplicitShape(
const Point *p,
const Color *c) {
Shape S;
S.P = *p;
S.C = *c;
S.V = vtableShape;
return S; }
/* destructor */
void
destroyShape(Shape *s) {
destroyColor(colorShape(s));
destroyPoint(pointShape(s));
}

$ cat Circle.h
#ifndef _Circle_h
#define _Circle_h 1

#include<Shape.h>

typedef struct {
Shape S; /* public base class */
double R; /* radius */
} Circle;
/* functions */
Shape*
shapeCircle(Circle* c);
double
radiusCircle(const Circle* c);
void
drawCircle(const Circle *c);
double
areaCircle(const Circle *c);
/* constructors */
Circle
createDefaultCircle(void);
Circle
createExplicitCircle(const Shape *s, double r);
/* destructor */
void
destroyCircle(Circle *c);

#endif /* _Circle_h */

$ cat Circle.c
/* gcc -I. -O2 -c Circle.c
*/
#include<math.h>
#include<stdio.h>
#include<Circle.h>

typedef void (*drawCircle_t)(const Circle *);
typedef double (*areaCircle_t)(const Circle *);
/* functions */
Shape*
shapeCircle(Circle* c) {
return &(c->S); }
double
radiusCircle(const Circle* c) {
return c->R; }
void
drawCircle(const Circle *c) {
fprintf(stderr, "drawCircle(const Circle *c)\n");
fflush(stderr); }
double
areaCircle(const Circle *c) {
const
double pi = 3.14159265358979323846;
double r = radiusCircle(c);
fprintf(stderr, "areaCircle(const Circle *c)\n");
fflush(stderr);
return pi*r*r; }
static virtual_t
vtableCircle[] = {(virtual_t)drawCircle,
(virtual_t)areaCircle};
/* constructors */
Circle
createDefaultCircle(void) {
Circle C;
C.S = createDefaultShape();
C.R = 0.0;
C.S.V = vtableCircle;
return C; }
Circle
createExplicitCircle(const Shape *s, double r) {
Circle C;
C.S = *s;
C.R = r;
C.S.V = vtableCircle;
return C; }
/* destructor */
void
destroyCircle(Circle *c) {
destroyShape(shapeCircle(c));
}

$ cat main.c
/* gcc -I. -O2 -o main main.c Circle.o Shape.o Color.o Point.o
*/
#include<stdio.h>
#include<Circle.h>

int
main(int argc, char* argv[]) {
Shape s = createDefaultShape();
Circle c = createExplicitCircle(&s, 2.0);
drawShape((Shape*)(&c));
fprintf(stdout, "%g = radius\t %g = area\n",
radiusCircle(&c), areaShape((Shape*)(&c)));
return 0;
}

$ cat Makefile
CC=gcc
DEFINES=
INCLUDE=-I.
OPTIONS=-O2
LIBRARY=
OBJECTS=Point.o Color.o Shape.o Circle.o
SOURCES=Point.c Color.c Shape.c Circle.c
HEADERS=Point.h Color.h Shape.h Circle.h
library=
COMPILE=$(CC) $(DEFINES) $(INCLUDE) $(LIBRARY) $(OPTIONS)

main: $(HEADERS) $(OBJECTS) main.c
$(COMPILE) -o main main.c $(OBJECTS) $(library)

Point.o: Point.h Point.c
$(COMPILE) -c Point.c

Color.o: Color.h Color.c
$(COMPILE) -c Color.c

Shape.o: Shape.h Shape.c
$(COMPILE) -c Shape.c

Circle.o: Circle.h Circle.c
$(COMPILE) -c Circle.c

clean:
rm $(OBJECTS) main

Nov 13 '05 #2
Hyoung Lee <hl**@dsplab.com> wrote:
A simple method of simulating a class, such as C++ or UML class, in C would
be using the struct construct. Similarly, we use C functions to simulate a
methods; e.g., rv method_a (&struct, parm_list); Other methods would be
fundamentally similar to this approach.

Are there any other approaches that would offer better maintainability and
readability? Do you have a better way of accurately simulating OO
visibility, inheritance, polymorphism, constructors, and destructors in C?


you can get single inheritance through the property that a pointer to a
structure is also a pointer to the first member of that structure.

in some of my code i have something like:

typedef struct object {
...
} object_t;

typedef struct thread {
object_t obj;
...
} thread_t;

struct server {
thread_t thr;
...
};

however, your initializations and destructions of these "objects" becomes so
tedious and verbose, it's difficult to defend.

in C, a better paradigm is to spend the vast majority of your time designing
on paper your C interfaces. then [physically] modularize-- assuming unix--
thru seperate processes and/or well-defined, abstract interfaces like pipes.

in java you might end up w/ an app that has several tens of thousands
of lines of code. you should never let yourself get that far in C.

at least, this has been my experience, albeit short.

- Bill

Nov 13 '05 #3
E. Robert Tisdale wrote:

<snip>

$ cat Point.h
#ifndef _Point_h
#define _Point_h 1


Just a nit: invasion of implementation namespace.

<snip>

--
Richard Heathfield : bi****@eton.powernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
Nov 13 '05 #4

"Hyoung Lee" <hl**@dsplab.com> wrote in message

Do you have a better way of accurately simulating OO
visibility, inheritance, polymorphism, constructors, and destructors in C?

It is reasonable to have opaque objects in C - the stdio FILE structure is
an example.

Constructors and destructors have to be called explicitly, but this isn't
too much of a burden on the calling programmer.

Once you start trying to provide inheirtance and polymorphism, its much
simpler to code in C++.

It can be done in C, for instance you can declare a structure containing
function pointers to act like a virtual interface, and you can nest
structures to provide a sort of inheritance. Microsoft's COM interface
provides a C API - I can't remember all the details but you obtain an
"unknown" function pinter and then query it to see what services the object
provides. However it is a horrible thing to have to use. C is really for
procedural programming, not object-orientation.
Nov 13 '05 #5
A simple method of simulating a class, such as C++ or UML class, in C would
be using the struct construct. Similarly, we use C functions to simulate a methods; e.g., rv method_a (&struct, parm_list); Other methods would be
fundamentally similar to this approach.

Are there any other approaches that would offer better maintainability and readability? Do you have a better way of accurately simulating OO
visibility, inheritance, polymorphism, constructors, and destructors in C?
Hyoung



"HongKongHooker" <su****@hooker.com> wrote in message
news:4sFOa.7547$OZ2.1355@rwcrnsc54... Would it be cruel if I asked why you're so interested in re-inventing C++?

"Hyoung Lee" <hl**@dsplab.com> wrote in message
news:Rm********************@twister.austin.rr.com. ..


Why would someone not learn C++ at this point ? It's a serious undertaking,
but you wouldn't have to use force C into an OOP mold ?

Sounds like stepping over boxes for weeks, rather than taking the time to
unpack.
Nov 13 '05 #6
"news.telesouth1.com" <no****@nospam.net> writes:

Why would someone not learn C++ at this point ? It's a serious undertaking,
but you wouldn't have to use force C into an OOP mold ?

There are many systems, e.g. embedded ones, where there is no C++
compiler available.

I came accross one approach which the author calls "C+":

<http://www.quantum-leaps.com/cookbook/cplus.htm>

Didn't the early C++ compilers emit C as an intermediate step? That
may be another way to do it.

--

John Devereux
Nov 13 '05 #7
On 09 Jul 2003 15:24:14 +0100, John Devereux <jd*@devereux.me.uk>
wrote:
"news.telesouth1.com" <no****@nospam.net> writes:

Why would someone not learn C++ at this point ? It's a serious undertaking,
but you wouldn't have to use force C into an OOP mold ?

There are many systems, e.g. embedded ones, where there is no C++
compiler available.


Fortunately, most embedded systems get along fine without "OO
visibility, inheritance, polymorphism, constructors, and destructors"
:-)
I came accross one approach which the author calls "C+":

<http://www.quantum-leaps.com/cookbook/cplus.htm>

Didn't the early C++ compilers emit C as an intermediate step? That
may be another way to do it.


Yep. Cfront.

--
Al Balmer
Balmer Consulting
re************************@att.net
Nov 13 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Last Timer | last post by:
class A { public: A(int a, int b) { this.a=a; this.b=b}; int a; int b; } class B : x(3), y(3), public A(1,3) {
10
by: Matthew | last post by:
I found an excellent tutorial on XML Serialization: http://addressof.com/blog/articles/ExploringXMLSerialization.aspx When he creates a class property, it looks like this: Public Class Drivers...
1
by: Gravy | last post by:
Hi, When I create a new reference to a webservice proxy class (one that was created when I imported a web reference) there is a slight delay. Can someone tell me what it's doing to cause this...
11
by: Marco Wedekind | last post by:
Hello all, I have a strange compiler behaviour with this code: ---- Begin of code snippet ---- class Base { public: static unsigned int ClassId();
11
by: bgreen | last post by:
I am hoping for some assistance with formatting a large text file which consists of a series of individual records. Each record includes specific labels/field names (a sample of 1 record (one of...
6
by: Big George | last post by:
Hello, I develop in ASP.NET with VB.NET code. I need some help constructing a class: Worker. I'm designing the properties of this class. The class is filled reading tables in database. ...
5
by: kylemort | last post by:
I am currently using a class (Card) to represent a card in a deck of cards. The class has a constructor: Card::Card(int num, int su) { suit = su; number = num; } and I am trying to create...
1
by: nabil | last post by:
Hi I have probleam while while initilazing nested class ... I needs to create a object 'b' of B(nested class) in A(surrounding class). while constructing b I have to pass pointer of funtion...
1
by: Brent White | last post by:
I can't figure out what I'm doing differently with this one drop-down list control from the other two that are working just fine. Background: I am constructing a page that will allow a user to...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
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...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

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.