Deklaration von struct-"Methoden"



  • mngbd schrieb:

    So seltsam ist das gar nicht. Würde man die Klammern um *p weglassen, wäre es die Deklaration einer Funktion p, die vom Typ int* ist.

    Das kann ich so nicht bestätigen. Lasse ich die Klammern weg, kann ich der Variablen keine Funktion zuweisen. Eine Funktion vom Typ int* sähe so aus:

    struct Blah {
        int *(*func) (void);
    };
    


  • Danke erstmal dafür! Sieht ja schonmal sehr verwirrend aus.

    Jetzt hätte ich nochmal ne Frage: Wenn ich das dann nachher irgendwie so habe

    struct MeineKlasse *meine_instanz = MeineKlasse.erzeuge_instanz();
    meine_instanz->instanzmethode();
    

    dann müsste ich ja, wenn ich in `instanzmethode` auf die "Instanz" zugreifen will, diese übergeben, zB mit

    meine_instanz->instanzmethode(meine_instanz);
    

    Zwar folgt C sowieso in keiner Weise dem DRY-Prinzip, aber jedesmal die Instanz übergeben, das halte ich für besonders doof. Irgendwelche Ideen?



  • So abwegig ist das gar nicht, zB haben Lua und Python bei Methoden als ersten Parameter self .

    Was tun? Entweder irgendwie dafür sorgen, dass eine Referenz im Hintergrund gehalten wird, oder eben als ersten Parameter übergeben. Die Schreibarbeit kann man sich auch mit Makros erleichtern.

    Zwar folgt C sowieso in keiner Weise dem DRY-Prinzip

    Was ist das denn?

    Das kann ich so nicht bestätigen. Lasse ich die Klammern weg, kann ich der Variablen keine Funktion zuweisen. Eine Funktion vom Typ int* sähe so aus:

    struct Blah {
        int *(*func) (void);
    };
    

    Missverständnis. Ich wollte nur darüber meckern, dass die Klammern um *func notwendig sind. Aber die sind schon gut so.



  • struct Blah foo = {&machwas};

    Den Adressoperator kann man übrigens bei Funktionen weglassen. Mit denen kann man nämlich nur zwei Dinge machen: sie aufrufen, und die Adresse bestimmen.



  • oder eben als ersten Parameter übergeben

    s/ersten Parameter/erstes Argument/
    </pedantic>



  • Hab jetzt mal ein wenig mit der Übergabe eines `self`-Arguments, das auf die "Instanz" zeigt, rumgespielt.

    Dabei trete ich auf folgendes Problem: Bei der Definition der Methoden-Signaturen im struct "Class" ist "Class" ja noch nicht definiert worden. Möchte ich jetzt also in diesem struct eine Methode definieren, die als erstes Argument einen Pointer auf eine "Class"-"Instanz" nimmt, ist dies schlichtweg nicht möglich. (?)

    Zur Verdeutlichung:

    typedef struct Class {
        int (*method)(Class *self); // schlägt fehl, da "Class" hier noch nicht definiert worden ist
    }
    

    Man könnte das so lösen, dass man als erstes Argument keinen "Pointer auf Class" nimmt, sondern einen Integerwert mit der Adresse, den man dann eben wieder zu einem "Pointer auf Class" konvertiert. Sieht aber nicht doll aus.



  • µngbd schrieb:

    Was tun? Entweder irgendwie dafür sorgen, dass eine Referenz im Hintergrund gehalten wird

    Wie genau meinst du das?

    Zwar folgt C sowieso in keiner Weise dem DRY-Prinzip

    Was ist das denn?

    http://de.wikipedia.org/wiki/DRY 😉

    Don’t-Repeat-Yourself (DRY, auch bekannt als Once and Only Once, dt. etwa: Wiederhole dich nicht) ist ein Prinzip, das besagt, Redundanz zu vermeiden oder zumindest zu reduzieren. Ein Anwendungsgebiet für das DRY-Prinzip ist z. B. die Programmierung.



  • dauerbaustelle schrieb:

    Dabei trete ich auf folgendes Problem: Bei der Definition der Methoden-Signaturen im struct "Class" ist "Class" ja noch nicht definiert worden. Möchte ich jetzt also in diesem struct eine Methode definieren, die als erstes Argument einen Pointer auf eine "Class"-"Instanz" nimmt, ist dies schlichtweg nicht möglich. (?)

    Zur Verdeutlichung:

    typedef struct Class {
        int (*method)(Class *self); // schlägt fehl, da "Class" hier noch nicht definiert worden ist
    }
    

    Wieso verwendest du ein typedef wenn du eh keinen neuen Bezeichner dafür definierst?! Außerdem fehlt ein Semikolon, wie schon mal erwähnt. Wenn du anstatt Class struct Class bennutzt geht's.

    struct Class {
        int (*method) (struct Class *self);
    };
    


  • dauerbaustelle schrieb:

    µngbd schrieb:

    Was tun? Entweder irgendwie dafür sorgen, dass eine Referenz im Hintergrund gehalten wird

    Wie genau meinst du das?

    Dazu habe ich keine konkrete Vorstellung. Aber Brainstroming: du könntest vor jedem Aufruf einen Zeiger auf das betroffene Objekt in einer globalen Variablen (oder so) speichern. Dann mit einem Makro (oder so) dafür sorgen, dass bei jedem Aufruf einer Methode dieser Zeiger richtig befüllt ist. Dass globale Variablen böse sind, weiss ich, aber es geht mir nur ums Prinzip.

    Don’t-Repeat-Yourself (DRY, auch bekannt als Once and Only Once, dt. etwa: Wiederhole dich nicht) ist ein Prinzip, das besagt, Redundanz zu vermeiden oder zumindest zu reduzieren. Ein Anwendungsgebiet für das DRY-Prinzip ist z. B. die Programmierung.

    Das klingt vernünftig. 🙂



  • dauerbaustelle schrieb:

    Zwar folgt C sowieso in keiner Weise dem DRY-Prinzip

    Was ist das denn?

    http://de.wikipedia.org/wiki/DRY 😉

    Don’t-Repeat-Yourself (DRY, auch bekannt als Once and Only Once, dt. etwa: Wiederhole dich nicht) ist ein Prinzip, das besagt, Redundanz zu vermeiden oder zumindest zu reduzieren. Ein Anwendungsgebiet für das DRY-Prinzip ist z. B. die Programmierung.

    ich finde das hat nix speziell mit C zu tun, sondern ist eher 'ne schlechte angewohnheit mancher (copy&paste) programmierer. z.b. wer ausgiebig 'const' benutzt, könnte auf die dumme idee kommen, funktionen doppelt anzulegen (eine const und eine nicht-const version).
    🙂



  • ;fricky schrieb:

    ich finde das hat nix speziell mit C zu tun, sondern ist eher 'ne schlechte angewohnheit mancher (copy&paste) programmierer.

    Schon richtig. Aber alte nichtobjektorientierte Sprachen verleiten einen ganz gerne mal dazu, doppelten Code zu schreiben. Wiederverwertbarkeit war damals noch nichts, über das man im Sprachdesign nachdachte.



  • volkard schrieb:

    Aber alte nichtobjektorientierte Sprachen verleiten einen ganz gerne mal dazu, doppelten Code zu schreiben.

    bis auf ganz wenige ausnahmen vielleicht. es gibt ja noch funktionen und makros. das DRY-prinzip einzuhalten ist selbst in assembler möglich.

    volkard schrieb:

    Wiederverwertbarkeit war damals noch nichts, über das man im Sprachdesign nachdachte.

    hat man zwar nicht, aber das kann einen doch nicht daran hindern, trotzdem wiederverwendbaren code zu schreiben.
    🙂


Anmelden zum Antworten