Ein praktische Demonstration [long]

27/01/2011 - 16:37 von Rainer Weikusat | Report spam
Damit das nicht immer so beziehungslos in der Gegend herumsteht, habe
ich mal ein kleines aber nicht mehr vollstaendig triviales
Demonstrationsprogramm fuer ein Klassenhierachie mit abgeleiteten
Klassen und ueberladenen virtuellen Methoden geschrieben. Es handelt
sich um eine Teil-Implementierung von einem Auswertungsbaum fuer
arithmetische Ausdruecke. Wie alle 'einfachen' OOP-Beispiel ist es
natuerlich zu einfach, um in sich vollstaendig ernstnehmbar zu
sein. Es soll auch lediglich das Prinzip mit Hilfe eines Beispiels,
das man uebersetzen und ausfuehren kann, demonstrieren.

Nein, ich bin nicht der Ansicht das 'statische Typueberpruefung' die
Welt vor explodierenden Raketen beschuetzen wird. Gegenbeispiele sind
schliesslich vorhanden.

Code below

/*
C OOP mini demonstration/ tree-based expression evaluation

This code is in the public domain (rweikusat@mssgmbh.com)
*/

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

/*
base class
*/
struct node_vtbl {
double (*value)(void *);
};

struct node {
void *vtbl;
};

double node_value(void *p)
{
struct node *this = p;
struct node_vtbl *vtbl = this->vtbl;

return vtbl->value(p);
}

/*
number class
*/
struct number {
struct node super;
double v;
};

double number_value(void *p)
{
struct number *this = p;
return this->v;
}

struct node_vtbl number_vtbl = {
.value = number_value
};

void *init_number(void *p, double v)
{
struct number *this = p;

this->super.vtbl = &number_vtbl;
this->v = v;

return this;
}

/*
unary operator
*/
struct unop_vtbl {
struct node_vtbl super;
double (*transform)(double);
};

struct unop {
struct node super;
void *child;
};

double unop_transform(void *p, double v)
{
struct unop *this = p;
struct unop_vtbl *vtbl = this->super.vtbl;

return vtbl->transform(v);
}

double unop_value(void *p)
{
struct unop *this = p;
return unop_transform(this, node_value(this->child));
}

/*
unary minus
*/
double unop_minus(double v)
{
return -v;
}

struct unop_vtbl unop_minus_vtbl = {
.super.value = unop_value,
.transform = unop_minus
};

void *init_unop_minus(void *p, void *child)
{
struct unop *this = p;

this->super.vtbl = (void *)&unop_minus_vtbl;
this->child = child;

return this;
}

/*
unary plus
*/
double unop_plus(double v)
{
return v;
}

struct unop_vtbl unop_plus_vtbl = {
.super.value = unop_value,
.transform = unop_plus
};

void *init_unop_plus(void *p, void *child)
{
struct unop *this = p;

this->super.vtbl = &unop_plus_vtbl;
this->child = child;

return this;
}

/*
binary operator
*/
struct binop_vtbl {
struct node_vtbl super;
double (*transform)(double, double);
};

struct binop {
struct node super;
void *left, *right;
};

double binop_transform(void *p, double left, double right)
{
struct binop *this = p;
struct binop_vtbl *vtbl = this->super.vtbl;

return vtbl->transform(left, right);
}

double binop_value(void *p)
{
struct binop *this = p;

return binop_transform(p,
node_value(this->left),
node_value(this->right));
}

/*
binary minus
*/
double binop_minus(double left, double right)
{
return left - right;
}

struct binop_vtbl binop_minus_vtbl = {
.super.value = binop_value,
.transform = binop_minus
};

void *init_binop_minus(void *p, void *left, void *right)
{
struct binop *this = p;

this->super.vtbl = &binop_minus_vtbl;
this->left = left;
this->right = right;

return this;
}

/*
binary plus
*/
double binop_plus(double left, double right)
{
return left + right;
}

struct binop_vtbl binop_plus_vtbl = {
.super.value = binop_value,
.transform = binop_plus
};

void *init_binop_plus(void *p, void *left, void *right)
{
struct binop *this = p;

this->super.vtbl = &binop_plus_vtbl;
this->left = left;
this->right = right;

return this;
}

/*
demo program
*/
int main(void)
{
struct binop b;
struct unop u;
struct number v0, v1;
struct node *tree;

/*
-(3 + 45)
*/
tree = init_unop_minus(&u,
init_binop_plus(&b,
init_number(&v0, 3),
init_number(&v1, 45)));

printf("value: %f", node_value(tree));
return 0;
}
 

Lesen sie die antworten

#1 Friedrich Dominicus
28/01/2011 - 07:18 | Warnen spam
Schönes Beispiel, und in der Form schon relativ dicht am COM Model.
In einer àhnlichen Form findet man es auch in der glib. Oder in der
GObject-Ecke (natürlich noch ausgebaut) wegen Basisdiensten von Objekten
etc.



Please remove just-for-news- to reply via e-mail.

Ähnliche fragen