Constructing Class in C

Discussion in 'C Programming' started by Hyoung Lee, Jul 8, 2003.

  1. Hyoung Lee

    Hyoung Lee Guest

    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
     
    Hyoung Lee, Jul 8, 2003
    #1
    1. Advertising

  2. 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
     
    E. Robert Tisdale, Jul 8, 2003
    #2
    1. Advertising

  3. 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?


    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
     
    William Ahern, Jul 8, 2003
    #3
  4. Richard Heathfield, Jul 8, 2003
    #4
  5. Hyoung Lee

    Malcolm Guest

    "Hyoung Lee" <> 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.
     
    Malcolm, Jul 8, 2003
    #5

  6. > > 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" <> 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" <> wrote in message
    > news:RmFOa.70343$...


    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.
     
    news.telesouth1.com, Jul 9, 2003
    #6
  7. "news.telesouth1.com" <> 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
     
    John Devereux, Jul 9, 2003
    #7
  8. Hyoung Lee

    Alan Balmer Guest

    On 09 Jul 2003 15:24:14 +0100, John Devereux <>
    wrote:

    >"news.telesouth1.com" <> 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
     
    Alan Balmer, Jul 9, 2003
    #8
    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. Todd Bandrowsky

    Constructing a Class Given a String

    Todd Bandrowsky, May 21, 2004, in forum: C++
    Replies:
    1
    Views:
    356
    Victor Bazarov
    May 21, 2004
  2. Last Timer
    Replies:
    7
    Views:
    348
    Mike Wahler
    Feb 9, 2005
  3. Big George

    Help constructing a class !

    Big George, Oct 12, 2006, in forum: ASP .Net
    Replies:
    6
    Views:
    343
    Sean Chambers
    Oct 13, 2006
  4. Replies:
    5
    Views:
    449
    =?iso-8859-1?q?Kirit_S=E6lensminde?=
    Mar 6, 2007
  5. Hicham Mouline
    Replies:
    3
    Views:
    482
    red floyd
    Nov 18, 2009
Loading...

Share This Page