Klassen: privat Funktion/Variable "verstecken"



  • @manni66 sagte in Klassen: privat Funktion/Variable "verstecken":

    Nein! Eine Klassendeklaration ist auch eine -definition.

    ?

    class test;
    


  • @Belli sagte in Klassen: privat Funktion/Variable "verstecken":

    @manni66 sagte in Klassen: privat Funktion/Variable "verstecken":

    Nein! Eine Klassendeklaration ist auch eine -definition.

    ?

    class test;
    

    Forward declaration



  • @manni66
    Ich glaube hier gibt es eine kleine Begriffsverwirrung.
    Das:

    class Foo {
    public:
        int bar();
        int baz();
    };
    

    ist eine vollständige Klassendefinition. Bloss die Member-Funktionen sind noch nicht definiert (aber bereits deklariert).



  • @axam Dein Hauptproblem ist, daß Du kein aktuelles Lehrbuch hast. C++ innerhalb eines Forenthreads zu vermitteln ist zum Scheitern verurteilt.

    // edit: blubb.

    // edit 2: @john-0 Du hast nicht verstanden ab wann eine Klasse definiert ist. +1 für @hustbaer ;

    @axam Vielleicht möchtest Du mal erklären was Du überhaupt erreichen möchtest? Visibility sollte nach meinem Link oben ja hoffentlich klar sein?



  • @axam
    Die Definition einer Klasse muss immer und überall (im ganzen Programm) gleich aussehen. Nicht auf den Buchstaben genau gleich, aber sie muss äquivalent sein. (Die genauen Regeln dazu welche Unterschiede erlaubt sind und welche nicht sind kompliziert und selten hilfreich, am besten gehst du davon aus dass jeder Unterschied verboten ist.)

    Und weiters gibt es noch die Regel dass eine Klasse pro Translation Unit nur 1x definiert werden darf. Das ändert aber nichts an der ersten Regel: wenn du 2 Translation Units hast, darf die Klasse natürlich pro TU 1x definiert werden, aber diese Definitionen müssen wie gesagt äquivalent sein.

    Das ist im übrigen auch ein Fehler den dir der Compiler nicht mitteilen wird. Also wenn du in zwei verschiedenen Files die selbe Klasse unterschiedlich definierst, dann kann es leicht sein dass du keine Fehlermeldung bekommst, dafür aber ein Programm das undefiniertes Verhalten hat. Also z.B. falsch rechnet oder abstürzt oder halt einfach irgendwas macht.



  • Möchte mich jetzt mal bei allen hier entschuldigen.
    Man sollte immer erstmal denken bevor man spricht.
    Hab mich da irgend wie in einen unsinnigen Gedanken verrannt, und mir ist inzwischen auch selbst klar geworden, warum soetwas nicht gehen kann und daß dies zu nichts führt.

    Trotzdem vielen Dank.
    Alerdings war dieses threat für mich dennoch sehr nützlich, denn vermutlich ist "PImpl Idiom" genau das, was ich gesucht habe.
    Zudem ist mir klar geworden, daß ich (geistig) nicht den Fehler machen darf eine Klasse mit .cpp und .h zu assoziieren (was jetzt im Nachhinein auch logisch ist, da mir ja bereits bekannt war, das ich ein Klasse auch direkt in die main.cpp schreiben könnte).

    Und @john-0, ein aktuelles Lehrbuch hätte mir bei meinem letztgenannten Denkfehler wohl auch nicht weiter geholfen, schließlich habe ich bereits dutzende Erklärungen gelesen, und mir ist trotzdem erst jetzt klar geworden, das ich von falschen Annahmen ausgehe.
    Werde mir jedoch in Zukunft etwas mehr Zeit lassen, bevor ich "dumme" fragen stelle, den wenn man erstmal eine Nacht darüber schläft, sieht die Welt plötzlich ganz anders aus.



  • @Swordfish sagte in Klassen: privat Funktion/Variable "verstecken":

    // edit 2: @john-0 Du hast nicht verstanden ab wann eine Klasse definiert ist. +1 für @hustbaer ;

    Wie immer ist es erbauend, wenn man einen Fehler in der Beschreibung gemacht hat, dass einem das notwendige Wissen abgesprochen wird.

    Also noch einmal sprachlich präzise.

    // example.h
    class Example; // Eine reine Deklaration einer Klasse, aber außer für opaque Zeiger vollkommen nutzlos.
    
    // Definition der Klasse, bis auf die member functions
    // Eine Definition kann nachher nicht mehr erweitert werden,
    // d.h. alle member müssen bei der Definition angegeben werden.
    // Nur member functions können später definiert werden.
    class Example {
        int value_;
    public:
        Example (const int value);
        int getValue () const;
    };
    
    // example.cc
    Example::Example(const int value) : value_ (value) {}
    
    int
    Example::getValue () const {
        return value_;
    }
    

    Wenn man stattdessen eine Template definiert, müssen die member functions auch direkt mit definiert werden. (Deshalb @hustbear würde ich nicht von einer vollständigen Definition reden, wenn die member functions nicht auch definiert wurden.)

    //example_template.h
    template <typename T>
    class Example {
        T value_;
    public:
        Example (const T& value) : value_ (value) {}
        T getValue () const {
            return this->value_;
        }
    }; 
    

    Nur Spezialisierungen können in einer eigenen Übersetzungeinheit definiert werden.

    Kommen wir zum eigentlichen Problem zurück. C++ erlaubt es nicht, die Definition einer Klasse später zu erweitern. D.h. die Klasse ist immer komplett sichtbar, aber member oder member functions sind nicht zugreifbar, wenn sie mit private oder protected geschützt sind. Das ist dann ein Problem, wenn man Implementationsdetails verstecken will. In C++ geht das im Gegensatz zu anderen OOP-Sprachen nicht, so dass man hier zum Proxy-Pattern bzw. Bridge-Pattern (auch PImpl-Idiom genannt) greifen muss.



  • @john-0 sagte in Klassen: privat Funktion/Variable "verstecken":

    // Definition der Klasse, bis auf die member functions

    Ja ne, eben nicht. Die Klasse ist definiert. Ich weiß nicht was der Halbsatz dahinter soll.



  • @Swordfish sagte in Klassen: privat Funktion/Variable "verstecken":

    Ja ne, eben nicht. Die Klasse ist definiert. Ich weiß nicht was der Halbsatz dahinter soll.

    Die Klasse ist nur formal definiert. Es geht gerade bei Anfänger darum zu vermitteln wie der Code korrekt zu organisieren ist. Die Member Functions können in einer Übersetzungseinheit separat definiert werden, aber sie können auch als Teil der Klassendefinition definiert werden. Was dann zum nächsten Problem führt, dass die One-Definition-Rule sich nur auf die Übersetzungseinheit bezieht und die Norm explizit erlaubt, dass N gleiche Kopien einer Klasse existieren – in N verschiedenen Übersetzungseinheiten. Womit der Linker wieder viel Arbeit bekommt.



  • Funktionen und Variablen Berechnungen zu programmieren finde ich noch immer eine der spannendsten Aufgaben. Vermutlich, weil ich Mathematik auch so gerne habe! 🤣


Anmelden zum Antworten