Hier mal eine einfache Variante für Quasi-Klassen in C (Betonung liegt auf Quasi für alle Querulanten):
/* "Basisklasse" mit gemeinsamen Eigenschaften aller Unterklassen */
typedef struct {
void(*ausgabe)(void*);
int z, ergebnis;
} BasisBerechner;
/* "Unterklasse" mit jeweiliger unterschiedlicher Implementierung */
typedef struct {
BasisBerechner basis;
void (*run)(void*,int);
} Berechner;
static void ausgabe(BasisBerechner *this)
{
printf("%d : %d\n",this->z,this->ergebnis);
}
static void plus(Berechner *this,int x)
{
this->basis.z++;
this->basis.ergebnis+=x;
}
static void minus(Berechner *this,int x)
{
this->basis.z++;
this->basis.ergebnis-=x;
}
#define CALLP(objekt,methode,p) objekt.methode(&objekt,p)
#define CALL(objekt,methode) objekt.methode(&objekt)
int main()
{
BasisBerechner bb={ausgabe}; /* Instanziierung einer "Basisklasse", in klassischer OOP natürlich widersinnig */
Berechner plusb={bb,plus},minusb={bb,minus}; /* Instanziierung zweier "Unterklassen" */
CALLP(plusb,run,1);
CALLP(plusb,run,2);
CALLP(plusb,run,3);
CALLP(minusb,run,1);
CALLP(minusb,run,2);
CALLP(minusb,run,3);
CALL(plusb,basis.ausgabe);
CALL(minusb,basis.ausgabe);
return 0;
}
Und für einen Vergleich mal eine C++ Variante:
using namespace std;
class BasisBerechner {
public:
BasisBerechner() : z(0),ergebnis(0){}
void ausgabe(){cout << z << " : " << ergebnis << endl;}
int z, ergebnis;
};
class BerechnerPlus : public BasisBerechner {
public:
void run(int i){++z;ergebnis+=i;}
};
class BerechnerMinus : public BasisBerechner {
public:
void run(int i){++z;ergebnis-=i;}
};
int main()
{
BerechnerPlus plusb;
BerechnerMinus minusb;
plusb.run(1);
plusb.run(2);
plusb.run(3);
minusb.run(1);
minusb.run(2);
minusb.run(3);
plusb.ausgabe();
minusb.ausgabe();
}
Man sieht für einfache Aufgabenstellungen geht sowas ohne Mehrcodierung in Größenordnungen.