Frage zum Verständnis zu Klassen und deren Kapselung
-
Hallo zusammen ich bins mal wieder,
ich sitze an der Aufgabe einen Punkt zu initialisieren und diesen dann zu verschieben. Das Programm läuft und funktioniert. Allerdings habe ich bei zwei stellen es über probieren geschaft nicht über die Logik. Event kann mir jm. weiterhelfen. Hier erst einmal mein Programm welches ich in eine Main, 2 ccp und zwei h files zerlegt habe.
#include "Point.h" #include "Circle.h" int main (void) { Circle c; Point p; p.init(1.2, 1.3); p.print(); c.init(p, 0.5); // 1. Übergebe ich hier mit p ein Objekt p der Klasse point? wenn ja is das eine Adresse? c.print(); c.move(0.8, 0.7); c.print(); return 0; }#pragma once #ifndef Point_h #define Point_h class Point { private: double x; double y; public: void init (double a, double b); void move (double dx, double dy); void print (bool newline=true); }; #endif#include "Point.h" #include <iostream> using namespace std; void Point::init(double a, double b) { x=a; // 2. könnte ich das auch mit dem this zeiger machen oder ist dies unüblich? y=b; // this->x=a; // this->y=b; }; void Point::move(double dx, double dy) { x+=dx; y+=dy; }; void Point::print(bool newline) { cout << "(" << x << ", " << y << ")"; if (newline) cout << endl; };#pragma once #ifndef Circle_h #define Circle_h #include "Point.h" class Circle { private: Point centre; double radius; public: void init (Point centre, double radius); void move (double dx, double dy); void print (bool newline=true); }; #endif#include "Circle.h" #include "Point.h" #include <iostream> using namespace std; void Circle::init (Point centre, double radius) { this->centre=centre; // 1. steht hier nun die Adresse des Objektes p? da ich ja, bei der untere Funktion mit centre.move auf die Funktion Point::move zugreife. Stimmt der Gedankengang so? this->radius=radius; }; void Circle::move (double dx, double dy) { centre.move(dx, dy); // 1. Ich rufe also über centre (was ja eigentlich Objekt p ist) die Funkion Point::move auf und übergebe die alten Werte von x und y? }; void Circle::print (bool newline) { cout << "<"; centre.print(false); cout << ", " << radius << ">"; if (newline) cout << endl; };1. Ich habe meine Gednken u Fragen in die Komentare gepackt, bitte entschuldigt der vielen code, ich dachte es ist so besser wie alles aus zu streichen.
Für mich ist es noch etwas verwirrend, da ich in einer Funktion von "Circle" auf eine Funktion von "Point" zugreifen kann und ich mir der Logik noch nicht ganz sicher bin.2. Nachdem ich den this Zeiger in der Funktion Circle verwendet hatte wollte ich dies auch bei Point versuchen und hat auch geklappt. Was ist den hier die gängige Form?
Mine Logik wäre für mich schlüsig, aber da ich keine Ahnung habe würde ich mich über eine kurze Rückmeldung zu meinen Gedanken freuen.
Herzlichen Dank!
-
Hallo,
// 1. Übergebe ich hier mit p ein Objekt p der Klasse point? wenn ja is das eine Adresse?
Ja du übergibst ein Object der Klasse p. Aber du übergibst das Objekt und keine Adresse. Also es wird eine Kopie angelegt.// 2. könnte ich das auch mit dem this zeiger machen oder ist dies unüblich?
Ja da x und y member der Klasse Point sind kannst du mit dem this pointer auf diese zugreifen. Ich finde das es ein schönerer stil ist wenn man this benutzt. Zumal es diverse Vorteile hat. Z.b. Wenn die übergebenen Variablen ähnliche oder gar gleiche namen haben wie die Attribute. Damit kann man diese bei ähnlichen Namen besser unterscheiden und bei gleichen Namen wird es sogar zur pflicht den this zeiger an zu geben da der compiler nicht unterscheiden könnte welche nun gemeint wäre.// 1. Ich rufe also über centre (was ja eigentlich Objekt p ist) die Funkion Point::move auf und übergebe die alten Werte von x und y?
Es ist nur eine Kopie des Objekt p. Du rufst also für die Kopie von obj p die move methode auf.// 1. steht hier nun die Adresse des Objektes p? da ich ja, bei der untere Funktion mit centre.move auf die Funktion Point::move zugreife. Stimmt der Gedankengang so?
Nein dort steht nun eine Kopie des object p drin.Alles in allem eigentlich gute Gedanken. Du solltest dir aber nochmal Referenzen, Pointer und Übergabewerte ansehen.
-
Schau dir mal Konstruktoren an. Dann brauchst du keine init-funktion. Der weitere Vorteil davon ist, dass dein Objekt idealerweise von Anfang an in einem sinnvollen Zustand ist.
-
@Synonym: danke das hat mir sehr geholfen udn ich werde deinen Tip mit Referenzund und Pointern folgen!
@Hyde++: Dazu komme ich im nächsten Kapittel des Buches, ich hoffe dann kommt der Aha efekt
