kleine Anfängerfragen zu Klassen



  • Ein freundliches Hallo an alle! 🙂

    Ich wollte einen kleinen Kampfsimulator bauen und dafür baue ich am Anfang Klassen, welche ich mir aber erst kürzlich angeeignet habe.
    Erste Version von meinem Programm war:

    class Ship
    {
    public:
            int att, shield, hull;
    };
    
    int main()
    {
         Ship schlachtschiff;
         schlachtschiff.att = 100;
         schlachtschiff.shield = 50;
         schlachtschiff.hull = 2000;
    }
    

    Soweit so gut.
    Dann habe ich constructors gelernt und habe es so umgebaut:

    class Ship
    {
    public:
            int att, shield, hull;
    
            Ship(int a, int b, int c)
            {
                att = a; shield = b; hull = c;
            }
    };
    
    int main()
    {
         Ship schlachtschiff(100, 50, 2000);
         // Ship kreuzer(30, 40, 1000);
         // weitere Schiffe ...
    }
    

    Der Code scheint Übersichtlichkeit & Schreibarbeit zu erleichtern und funktioniert auch. Ist dies der Sinn von constructors?
    (Soweit irgendwelche Einwände? vllt speziell Effizienz betreffend, von der ich natürlich noch nicht so viel Ahnung habe. wird das so von Profis in der Praxis auch gemacht?).

    1) Frage: Wenn ich nun solche constructors benutze, wie greife ich dann z.B. auf den Wert "Angriff vom Schlachschiff" zu? auch über "schlachtschiff.att" ? gibt es andere Befehle womit ich quasi in dem Fall an die "100" komme?
    2) Stichpunkt private/public:
    Oben habe ich public für die Membervariablen att, shield & hull gewählt.
    wenn ich aber private wähle, funktioniert es nicht mehr 😞
    Ich dachte, dass Memberfunktionen einer Klasse immer Zugriff auf alles andere innerhalb der selben Klasse haben. Aber der Compiler meckert, dass ich nicht auf att zugreifen kann, sobald ich im Code bei "Ship schlachtschiff(100,.." ankomme, also schlachtschiff.att auf 100 setzen möchte. (Ich rufe doch die Memberfunktion, also den constructor welcher nur eine spezielle Memberfunktion ist, auf, und dieser dann die Membervariablen.) Warum kann der constructor hier nicht auf die privaten Variablen zugreifen?
    3) Ich sehe in vielen versch. Quellen, dass die Memberfunktionen außerhalb der Klasse definiert werden.
    In meinem Fall sowas wie:

    class Ship
    {
    public:
            int att, shield, hull;
    
            Ship(int a, int b, int c); //Deklaration
    };
    Ship::Ship(int a, int b, int c){ //Definition
          att = a; shield = b; hull = c;}
    

    Ich hatte entgegen diesen Beispielen überall, den constructor innerhalb meiner Klasse definiert. (Ich hatte es selbständig versucht und es funktioniert).
    Könnten dadurch Probleme auftreten?

    Ich hoffe, dass diese Fragen nicht zu einfältig und beantwortbar sind.
    Mit freundlichen Grüßen,
    Hetorius



  • Hectorius schrieb:

    Der Code scheint Übersichtlichkeit & Schreibarbeit zu erleichtern und funktioniert auch. Ist dies der Sinn von constructors?

    Die Frage kann man auf zwei Weisen verstehen. Falls du wissen willst, ob es richtig war, hier einen Konstruktor zu benutzen: Vermutlich ja. Man kann das nicht eindeutig beantworten, weil die Klasse zu simpel ist und man nicht unbedingt vorhersehen kann, wie sie mal benutzt werden wird. Falls du wissen willst, warum es überhaupt Konstruktoren gibt: Um Instanzen von Klassen in einen gültigen Zustand zu versetzen.

    (Soweit irgendwelche Einwände? vllt speziell Effizienz betreffend, von der ich natürlich noch nicht so viel Ahnung habe. wird das so von Profis in der Praxis auch gemacht?).

    Was erwartest du denn bei drei Zuweisungen an möglichen Effizienzsteigerungen?

    Ich würde das Teil übrigens nicht mit class, sondern mit struct deklarieren. Das macht technisch keinen großen Unterschied, aber class sind für mich komplexe Typen, die eine Schnittstelle haben, eine Abstraktion darstellen, inneren Zustand kapseln, möglicherweise polymorph sind usw. Dein Typ ist nur eine Ansammlung von drei öffentlichen Variablen.

    1) Frage: Wenn ich nun solche constructors benutze, wie greife ich dann z.B. auf den Wert "Angriff vom Schlachschiff" zu? auch über "schlachtschiff.att" ?

    Genauso wie ohne Konstruktor, es ändert sich dadurch nichts.

    gibt es andere Befehle womit ich quasi in dem Fall an die "100" komme?

    Was meinst du damit?

    2) Stichpunkt private/public:
    Oben habe ich public für die Membervariablen att, shield & hull gewählt.
    wenn ich aber private wähle, funktioniert es nicht mehr 😞
    Ich dachte, dass Memberfunktionen einer Klasse immer Zugriff auf alles andere innerhalb der selben Klasse haben. Aber der Compiler meckert, dass ich nicht auf att zugreifen kann, sobald ich im Code bei "Ship schlachtschiff(100,.." ankomme, also schlachtschiff.att auf 100 setzen möchte. (Ich rufe doch die Memberfunktion, also den constructor welcher nur eine spezielle Memberfunktion ist, auf, und dieser dann die Membervariablen.)

    Was meinst du mit "sobald du im Code ... ankommst"? Compilierst du von Hand, hast du einen Interpreter oder was? Meinst du, der Compiler meldet den Fehler an der Stelle? Poste im Zweifel die vollständige Fehlermeldung sowie den vollständigen Code. So wie es dasteht (+ private) dürfte ein derartiger Fehler jedenfalls nicht auftreten. Vielleicht versuchst du in main auf schlachtschiff.att zuzugreifen (was nicht dasteht), das geht natürlich nicht mehr, da main keine Memberfunktion der Klasse ist.

    3) Ich sehe in vielen versch. Quellen, dass die Memberfunktionen außerhalb der Klasse definiert werden.
    In meinem Fall sowas wie:

    class Ship
    {
    public:
            int att, shield, hull;
    
            Ship(int a, int b, int c); //Deklaration
    };
    Ship::Ship(int a, int b, int c){ //Definition
          att = a; shield = b; hull = c;}
    

    Ich hatte entgegen diesen Beispielen überall, den constructor innerhalb meiner Klasse definiert. (Ich hatte es selbständig versucht und es funktioniert).
    Könnten dadurch Probleme auftreten?

    Ja, aber das sollte dich im Moment nicht kümmern. Richte dich für den Anfang nach der Regel, dass du Memberfunktionen immer außerhalb der Klasse (und zwar in einem eigenen Sourcefile, nicht im Header) definierst, mit Ausnahme sehr kurzer und einfacher Funktionen.



  • danke Bashar!
    ich verstehe deine Erläuterungen, und es scheint nur noch hier ein Problem zu geben:

    Bashar schrieb:

    Was meinst du mit "sobald du im Code ... ankommst"? Compilierst du von Hand, hast du einen Interpreter oder was? Meinst du, der Compiler meldet den Fehler an der Stelle? Poste im Zweifel die vollständige Fehlermeldung sowie den vollständigen Code. So wie es dasteht (+ private) dürfte ein derartiger Fehler jedenfalls nicht auftreten. Vielleicht versuchst du in main auf schlachtschiff.att zuzugreifen (was nicht dasteht), das geht natürlich nicht mehr, da main keine Memberfunktion der Klasse ist.

    Ja, wenn ich oben statt "public" "private" schreibe, meldet der Compiler einen Fehler, an der Stelle sobald ich meinem Objekt "schlachtschiff" (in der main-Fkt) die Werte zuweisen möchte.

    Also im Prinzip ist es das, was du sagst:

    Bashar schrieb:

    das geht natürlich nicht mehr, da main keine Memberfunktion der Klasse ist

    aber... ich verstehe die Programmlogik dann nicht.
    ich rufe doch mit

    Ship schlachtschiff(100, 50, 2000);
    

    die Memberfunktion "Ship", also den contructor auf

    Ship(int a, int b, int c)
    

    , welcher dann erst die Membervariablen benutzt. also passiert doch eigtl. alles innerhalb der Klasse, weshalb ich nicht verstehe, warum private dann den Zugriff verbietet 😞



  • Ich hab grad keine Lust auf Ratespielchen, einmal sagst du, dass du die Werte in main zuweist, dann wieder macht es der Konstruktor.

    Poste die vollständige Fehlermeldung und den dazugehörigen Code.



  • ah, ich denke es hat sich erledigt.
    habe jetzt verstanden, dass man private Membervariablen nicht mal lesen darf, also auf keinster Weise von main() aus zugreifen darf.
    also z.B. ein simples "std::cout<<schlachtschiff.att;" ist nicht erlaubt.

    ich danke dir 😉


Log in to reply