C++-Programm mit Polymorphie als C-Programm schreiben



  • Hallo!

    Wir haben ein C++-Programm zur Manipulation, Darstellung und Berechnung von Ausdrücken erhalten , welches wir als C-Programm umschreiben sollen. Das Problem ist, dass das Programm Polymorphie nutzt, und wir es in C umschreiben sollen.

    Alles was ihr wissen müsst:
    http://people.freenet.de/Gayson/expr.cpp (Originalquellcode)
    http://people.freenet.de/Gayson/expr-gekuerzt.cpp (Orignalquellcode, ein wenig gekürzt, habe die Klassen Minus, Mal und Durch weggelassen)
    http://people.freenet.de/Gayson/expr.jpg (Vererbungsdiagramm)

    Das C-Programm soll im Anschluss folgendes Aussehen haben:
    http://people.freenet.de/Gayson/expr_template.c

    Dazu sollen wir uns virtuelle Methodentabellen in C basteln, die uns in einer Vorlesung mit Funktionspointern etc. vorgestellt worden ist:

    struct Base_vtable_layout{
    void (*f1)();
    int (*f2)(int);
    };
    struct Base_vtable_layout Base_vtable = {
    &Base_f1, &Base_f2
    };
    

    ----------------------------------------------------------------------

    Ich habe folgende Frage, die ich mir einfach nicht beantworten kann, und die wahrscheinlich für das Verstehen des zu schreibenden Programms wichtig ist:
    In expr_template.c steht in Zeile 7 wahrscheinlich ein Makroname, was noch definiert werden müsste. Nur Frage ich mich, wie dieses Makro aussehen soll. Ich dachte mir sowas:

    #define ALLOCATE(a,b) struct a b;
    

    Wobei ich dann halt jeweils noch ein struct Plus, struct Minus etc. schreiben müsste. Doch wie sähe ein solches struct Plus aus? Es müsste doch Expr e1, Expr e2 und ein struct Expr base = {&Plus_eval, &Plus_precedence, &Plus_print}; enthalten, wobei ich Expr folgendermaßen geschrieben hätte:

    struct Expr{
    	void (*eval)();
    	int (*precedence)();
    	void (*print)();
    };
    

    ----------------------------------------------------------------------

    Habt ihr irgendwelche Ideen? Ich verstehe nämlich dann nicht Zeile 8 und 9, bzw. wie z.B. in struct Plus e1 und e2 gespeichert werden, sodass diese später aufrufbar wären...
    Wäre wirklich nett, wenn ihr mir helfen könntet, denn ich habe noch nie wirklich mit Polymorphie gearbeitet :(.

    Danke an alle, die sich das durchgelesen haben!



  • Hi Uwe,

    ich galub, wir sitzen da am gleichen Problem...
    Schon was rausgefunden? Also ich kann damit auch nichts anfangen....



  • Für Ableitung ginge sowas:

    struct Expr
    {
        void(*print)(Expr*);
       // usw. für jede virtuelle Methode
    };
    
    struct Number
    {
        Expr expr;
    
        int value;
    };
    
    struct Plus
    {
        Expr expr;
        ...
    };
    
    usw.
    

    Jetzt lassen sich in jedem Typ die Methodenzeiger speichern.

    Das ALLOC-Macro könnte man so schreiben:

    #define ALLOC(Type, var) \
        Type* var = malloc(sizeof(Type)); \
        var->expr.print = Type ## _print; \
        usw. für jede Methode
    

    Type ## _print macht der Präprozessor zu Type_print, also zB. Number_print.

    Mit Konstruktor sähe das dann so aus:

    void Number_print(Expr* e)
    {
    ...
    }
    
    Expr* number(int value)
    {
        ALLOC(Number, num);
        num->value = value;
        return (Expr*)num;
    }
    

    Und da ist die Polymorphie:

    Expr* e = number(123);
    e->expr.print(e);
    

    Jenachdem welche Expr wirklich hinter e steckt wird die entsprechende Methode aufgerufen.


Anmelden zum Antworten