Klassen verständniss
-
Hallo
ich habe ein kleines Prob. mit Klassen. Ich möchte ein Prog in dem ich mehrer Fahrzeuge verwalte, nun mein Problem. Wenn ich ein Kennzeichen (zb. a-aa 666) anlege und ein neues Objekt anlege wie kann ich dieses Objekt später ansprechen?

-
Wie hast du dein Objekt denn angelegt?
class automobil { string zeichen; automobil(const string& z) : zeichen(z) {} }; automobil a("a-aa 666"); string kennzeichen = a.zeichen;[edit]
Klassenname geändert.
So besser.
[edit]
-
Wobei auto natürlich ein denkbar schlechter Namen für eine Klasse ist

-
[
class Auto{ float kmAlt; float kmNeu; float lieter; float gefahren; float verbrauch; public: ....]
im prinziep erst mal ne grundidee
-
Braunstein schrieb:
class automobil { string zeichen; automobil(const string& z) : zeichen(z) {} };alles 'private' *ggg*
@rest: wenn du ein objekt direkt anlegst, dann mit dem punkt 'object.member = ...'
solltest du mit 'new' arbeiten dann 'object->member = ...'
-
Das es jetzt private ist, liegt daran, dass ich eigentlich erst eine struct machen wollte, mich dann aber kurzfristig für class entschieden hab um den OP nicht zu verwirren. Irgendwie hab ich dann wohl das public: vergessen.

-
Übrigens widerspricht der direkte Zugriff von außen den (üblichen) Schutzbeschränkungen für Klassen. Schließlich sind die Member "private", DAMIT niemand darin rumpfuschen kann. Besser dürfte die Auto-Klasse also so aussehen:
class Auto { string kennz; public: Auto(const string& k) : kennz(k) {} void set_kennz(const string& k) {kennz=k;}//nur wenn du der Meinung bist, das Kennzeichen nachträglich ändern zu wollen string get_kennz() { return kennz;} };(dieser Ansatz hat den Vorteil, daß du im Setter noch eine Fehlerkontrolle einbauen (oder ihn ganzweglassen) kannst)
-
string const& get_kennz() { return kennz;}wir wollen ja nicht, daß die freien attribute schneller sind.
-
ich würde es außerdem erlauben, die methoden auch über konstante referenzen auf das objekt aufzurufen:
const string &get_kennz() const { return kennz;} string get_kennzKopie() const { return kennz;} //kopie kann auch nützlich seinzum beispiel mit so einer funktion:
void test(const Auto &a) { cout << a.get_kennz() << endl; }
-
Sorry doppelmoppel, aber deine 2. Methode ist sinnlos!
Es reicht, die konstante Referenz zurückzugeben.Schließlich kann man eine Kopie ja jederzeit mit
Auto a; std::string sKennzeichen = a.get_kennz();anlegen.
-
Th schrieb:
Sorry doppelmoppel, aber deine 2. Methode ist sinnlos!
stimmt. ich hatte eigentlich an folgendes szenario gedacht:
void test(string &s); ... Auto a("bla"); test(a.get_kennzKopie());aber referenzen auf nicht const sind ja mit temporaries verboten
-
test(a.get_kennzKopie()); ergibt keinen sinn, wenn test die kopie ändert.
-
volkard schrieb:
test(a.get_kennzKopie()); ergibt keinen sinn, wenn test die kopie ändert.
es ergibt nur dann keinen sinn, wenn test nichts anderes macht, als die kopie zu ändern. es kann ja sein, dass test viele andere sinnvolle sachen macht, und die veränderung des parameters ignoriert werden darf.
-
Die Signatur der Funktion sagt das sie für eine Modifikation des übergebenen Parameters zuständig ist. Die vielen anderen nützlichen Dinge wären Seiteneffekte.
Das nutzen von Seiteneffekten bedeutet jedoch sich mit undefinierten verhalten einzulassen, da sich die Implementierung von test jederzeit ändern kann.
Da ja aber keiner undefiniertes verhalten haben will (also keine Seiteneffekte) ist der Aufruf von test mit einer Kopie eines Wertes der gezeigten Art ohne effekt.
IMHO braucht man keine Methode in einer Klasse, wenn diese die internen Daten per const ref zurück liefert. Wird dennoch eine Kopie benötigt, so möge diese der Client der Klasse erzeugen. Dieser kann durch das Wissen wofür er diese benötigt viel effizienter/zielgerichteter anlegen.
-
aber mit getKennzKopie spart man drei Zeichen beim tippen.
test(a.getKennzKopie()); test(string(a.getKennz()));auch ein netter vorschlag, damit kopiegetter nicht immer eingebaut werden müssen:
template<typename T> T kopie(T const& t){ return t; } test(kopie(a.getKennz()));mann, bin ich heute wieder fantasievoll.

-
3 Zeichen, da fehlt ne klammer

grrrr - hat er doch noch schnell nachgezählt

-
Knuddlbaer schrieb:
Die Signatur der Funktion sagt das sie für eine Modifikation des übergebenen Parameters zuständig ist. Die vielen anderen nützlichen Dinge wären Seiteneffekte.
Eine Funktion mit Rückgabetyp void, die Seiteneffekte verursacht; wer hätte das gedacht?
Die Modifikation des übergebenen Parameters kann evtl. auch eine ignorierbare Log-Funktionalität darstellen.
-
Ich sehe hier erst einmal das Bedürfnis meine Sicht von Seiteneffekten zu erläutern um missverständnisse von flamen zu unterschieden:
Unter Seiteneffekt verstehe ich, das die Funktion Daten verändert die nicht offensichtlich sind.
void x::test(T & t) { // Seiteneffekte intern_ganz_viel_am_internen_objekt_aendern(); t += 2; }Und was wenn x::test nun davon ausgeht, das t wirklich geändert wurde ?
Drehen wir den Spieß doch mal um:
Nenne einen konkreten Fall in dem man einer Routine, die Werte ändert und deren Implementierung unbekannt ist, eine Kopie des zu ändernden Wertes übergeben sollte und warum dies kein Risiko betreffend undefinierten Verhaltens ist.
Ebenso wäre es interesannt Deine Sicht der Designentscheidung zu erfahren einer solchen Routine eine aufwendige und teure Kopie zu übergeben.
Mir fällt dazu nur das ausnutzen von Seiteneffekten (s.o.) zu verwenden und die eigentliche Aufgabe der Routine wegzuwerfen.
(Das es in der Praxis viele Routinen gibt die T & annehmen aber keine Änderung des Wertes vornehmen sei als bekannt hingestellt aber nicht als garantiert).
Ich lerne doch gerne was neues dazu - und bitte nich als Flame verstehen
-
Knuddlbaer schrieb:
(Das es in der Praxis viele Routinen gibt die T & annehmen aber keine Änderung des Wertes vornehmen sei als bekannt hingestellt aber nicht als garantiert).
nee, ist mir neu.
-
Na dann von mir aus auch T * und nen Blick in die WinApi oder so macher kommerziellen Lib, den Quellcode vom Cheffe ....
In dem was zum standard gehört kann ich Dir keinen einzigen Fall nennen (weils den nich gibt oder ich mich nich auskenne mit C++)
-
Knuddlbaer schrieb:
Na dann von mir aus auch T * und nen Blick in die WinApi oder so macher kommerziellen Lib, den Quellcode vom Cheffe ....
In dem was zum stan**** gehört kann ich Dir keinen einzigen Fall nennen (weils den nich gibt oder ich mich nich auskenne mit C++)in libs, die sooo alt sind, daß sie in c vor 1999 geschrieben wurden. da mögen T* vorkommen, wo T const* gemeint ist.