OO-ohjelmointi

phadej 12.04.06 15:40

Kaikki on tälläistä kokeileet varmasti joskus, kääntyi linuxin gcc:llä -ansi vipulla, tiedä sitten mitä tuokin tarkoitti.

 Tekstiversio  Arvo: 0 (4 ääntä)  Äänestä: +  -
/*
 * Dummy example about OO-programming in C
 * Author: Oleg Grenrus <phadej@gmail.com>
 */


#include <stdio.h>
#include <stdlib.h>

typedef enum {false, true} bool;

/* virtual functions */
typedef enum {PRINT} Car_functions;

/* parent class */
typedef struct __TCar {
        void (**_functions)();
        int year;
} *TCar;

/* function declarations */
void TCar_print(TCar t);

/* function array */
void (*TCar_functions[])() = {
        TCar_print
};

/* child classes
 *
 * notice that parent fields are at the same place, important!
 */

typedef struct __TToyota {
        void (**_functions)();
        int year;
        char *model;
} *TToyota;

void TToyota_print(TToyota t);

void (*TToyota_functions[])() = {
        TToyota_print
};

typedef struct __TVolvo {
        void (**_functions)();
        int year;
        bool tractor;
        int wheels;
} *TVolvo;

void TVolvo_print(TVolvo t);

void (*TVolvo_functions[])() = {
        TVolvo_print
};

/* car constuctor */
TCar TCar_construct(TCar t, int year) {
        TCar _t;
       
        if (!t)
                _t = (TCar) malloc(sizeof(struct __TCar));
        else
                _t = t;

        _t->_functions = TCar_functions;
        _t->year = year;

        return _t;
}

/* toyota constructor */
TToyota TToyota_construct(TToyota t, int year, char *model) {
        TToyota _t;
       
        if (!t)
                _t = (TToyota) malloc(sizeof(struct __TToyota));
        else
                _t = t;

        /* parent constructor */
        TCar_construct((TCar) _t, year);
       
        _t->_functions = TToyota_functions;
        _t->model = model;
       
        return _t;
}

/* volvo constructor */
TVolvo TVolvo_construct(TVolvo t, int year, bool tractor, int wheels) {
        TVolvo _t;
       
        if (!t) 
                _t = (TVolvo) malloc(sizeof(struct __TVolvo));
        else
                _t = t;

        /* parent constructor */
        TCar_construct((TCar) _t, year);
       
        _t->_functions = TVolvo_functions;
        _t->tractor = tractor;
        _t->wheels = wheels;
       
        return _t;
}

/* car print */
void TCar_print(TCar t) {
        printf("Car\n  year     : %d\n", t->year);     
}

/* toyota print, calls parent print too */
void TToyota_print(TToyota t) {
        TCar_print((TCar) t);
        printf("  mark     : Toyota\n  model    : %s\n", t->model);
}

/* voldo print, calls parent print too */
void TVolvo_print(TVolvo t) {
        TCar_print((TCar) t);
        printf("  mark     : Volvo\n  tracktor : %s\n  wheels   : %d\n",
                                t->tractor ? "yes" : "no", t->wheels);
}

/* abstract car print, dont care of type of car */
void Car_print(TCar t) {
        void (*fp)(TCar t);
        fp = t->_functions[PRINT];
        fp(t);
}

/* example */
int main() {
        TCar cars[10];
        int i;
       
        for (i = 0; i < 10; ++i) {
                if (i % 2)
                        cars[i] = (TCar)TVolvo_construct(NULL, 1990+i, i & 0x2, i%4);
                else
                        cars[i] = (TCar)TToyota_construct(NULL, 1980+i, "carina");
        }

        for (i = 0; i < 10; ++i) {
                Car_print(cars[i]);
        }
       
        return 0;
}
 

Ztane 12:56 13.4.06 
Öhm... tää ny on tehty takaperosesti.

Parempi laittaa olioihin pointteri virtual tableen niin noita luokkia pystyyki ylikuormittaan oikeesti!
phadej 13:22 13.4.06 
Kuuneltii Ztanen kommentia, ja totta mooses, näin on selvempää. Ja nythän pystyy periä toisesta filustakin.
Mutta niinkuin todettu, tämä on hankalaa, turhaankos c++ keksittiin.