Daten- / Funktionskappselung



  • SeppJ schrieb:

    Ja. So kann der Compiler die richtige Benutzung der Typen überprüfen, da er dann Stack und Queue unterscheiden kann.

    Dann muss ich ja sicherlich beim Aufrufen der internen Meta-Listen-Funtktionen diese entsprechend casten. Also:

    STACK stinit() {
    return (STACK) meta_list_init();
    }
    

    Um dieser hin und her Casterei zu entgehen hab ich mich für den obigen Ansatz entschieden. Denke aber mal auch nach deiner Erläuterung der besseren Unterscheidung wegen, ist dies besser.


  • Mod

    Nirvash schrieb:

    Dann muss ich ja sicherlich beim Aufrufen der internen Meta-Listen-Funtktionen diese entsprechend casten. Also:

    STACK stinit() {
    return (STACK) meta_list_init();
    }
    

    Wo solltest du so etwas benötigen?



  • Naja die init Funktion der Meta-Liste liefert ein Pointer auf eine Meta-Liste zurück, rufe ich dieses aus der Stack Initialisierungs Funktion auf, welche ja einen Pointer auf einen Stack zurückliefern soll, so muss der Rückgabewert von Meta-Listen-Pointer nach Stack-Pointer umgewandelt werden?
    Oder fällt das Weg, wenn die definierten Structs für Meta-Liste und Stack genau gleich aussehen, nur einen anderen Namen haben?


  • Mod

    Ich hätte eher an so etwas gedacht:

    typedef struct
    {
      ML ml;
    } Stack;
    
    Stack init_stack()
    {
      Stack stack;
      stack.ml = init_ml();
      return stack;
    }
    


  • SeppJ schrieb:

    Ich hätte eher an so etwas gedacht:

    typedef struct
    {
      ML ml;
    } Stack;
    
    Stack init_stack()
    {
      Stack stack;
      stack.ml = init_ml();
      return stack;
    }
    

    Ok, das klingt plausbilder und handhabbarer als was ich versucht hab zurecht zu basteln. Ich nehme an, damit kann ich auch mehrere Stacks parallel erstellen, da für jeden Funktionsaufruf eine neue Instanz generiert wird?

    Dieser Umstand hat mich bisher immer ein wenig irritiert, wenn ich eigene Bibliotheken schreibe: Wie bekomme ich es hin, von dem Datenobjekt nicht nur eines, sondern mehrere Erzeugen zu können, auf die ich auch getrennt voneinander zugreifen kann. Mit dieser von dir beschriebenen Methode ist es super einfach und ich komm mir selbst bisschen dämlich vor, nicht selbst drauf gekommen zu sein 😃
    Vielen Dank!


  • Mod

    Nirvash schrieb:

    Ok, das klingt plausbilder und handhabbarer als was ich versucht hab zurecht zu basteln. Ich nehme an, damit kann ich auch mehrere Stacks parallel erstellen, da für jeden Funktionsaufruf eine neue Instanz generiert wird?

    Ja. War das bei deiner Originalliste denn nicht so?



  • SeppJ schrieb:

    Ja. War das bei deiner Originalliste denn nicht so?

    Es war so, nur umständlicher gestaltet. Mir war

    typedef struct
    {
      ML ml;
    } Stack;
    

    noch nicht so gut bekannt, da ich bisher immer mit:

    typedef struct _stack Stack
    
    struct _stack
    {
      ML ml;
    };
    

    gearbeitet habe und dann für ein neues Element dieses Structs immer mit malloc den jeweiligen Speicher reserviert. Bei dir viel das jetzt weg für ein neues Stack-Element, daher gehe ich davon aus, der Speicher wird dann automatisch durch den speziellen typedef struct {}; <Name> allokiert?


  • Mod

    😕
    Ich habe das Gefühl, du redest von Syntax, obwohl du auch von Speicher und malloc redest.

    typedef struct
    {
      ML ml;
    } Stack;
    

    Macht bezüglich des Programmablaufs gar nichts. Das holt keinen Speicher, führt nichts aus, ist keine Variable. Das macht dem Compiler einfach nur ein struct mit der Form

    struct
    {
      ML ml;
    };
    

    unter dem Namen "Stack" bekannt.



  • Oh ok, dann hab ich mich selbst etwas verwirrt 😃

    In deiner init_stack Funktion wird der Stack ja nicht als Pointer-Referenz, sondern als normales Objekt erstellt. Da hab ich nicht ganz aufgepasst.



  • SeppJ schrieb:

    Ich hätte eher an so etwas gedacht:

    ....

    Stack init_stack()
    {
    Stack stack;
    stack.ml = init_ml();
    return stack;
    }[/code]

    Ist die Variable stack nicht hier nur lokal?
    Wieso ist sie nach dem Verlassen der init_stack noch gültig?


  • Mod

    HugoK schrieb:

    Ist die Variable stack nicht hier nur lokal?

    Ja.

    Wieso ist sie nach dem Verlassen der init_stack noch gültig?

    Ist sie auch nicht. Aber ihre Kopie ist gültig.

    Das ist wie bei ganz einfachen Funktionen, lass dich nicht von den verrückten Namen der Datentypen verwirren:

    int sum(int a, int b)
    {
      int result = a + b;
    
      return result;
    }
    

    Da wunderst du dich sicher auch nicht, ob das Ergebnis noch gültig ist, oder?


Anmelden zum Antworten