objekte zu anderen objekten hinzufügen
-
peterli schrieb:
...
dass ich im prinzip über eine methode im objekt klaus ein auto hinzufügen kann oder beliebig dann halt in eine liste hängen kann.kann mir da jemand die genaue syntax geben, wie des ganz einfach geht?...
Du beschreibst hier, was man eine "Assoziation" nennt - leider etwas zu knapp, um konkret helfen zu können: Wie viele Autos soll ein Fahrer haben können (1, mehrere) ?
Wieviele Fahrer ein Auto ?
MUSS ein Fahrer ein Auto haben ?
MUSS ein Auto einen Fahrer haben ?
Kann ein Fahrer sein Auto wechseln oder ein Auto seinen Fahrer ?EDIT: Außerdem wichtig: Sind ihre Lebenszeiten verknüpft ? Kann das Eine ohne das Andere existieren ?
Gruß,
Simon2.
-
hi
erst mal danke für die rege antwortfreude!!

vom prinzip ist es schon so ganz gut getroffen, wie DeSoVoDaMu es gemacht hat.
ein fahrer soll nur ein auto haben, mehr nicht.
und des einfach über ne methode hinzufügen.
ich glaub dass des dann so passt, oder?
class fahrer { private: Auto m_auto; public: kaufen(Auto const* car) { m_auto=car; } }; // ... klaus.kaufen(&bmw);gruß
peter
-
@DeSoVoDaMu: Wieso benutzt du Zeiger und riskierst so vllt ungültige Objekte ???
Ein list<Auto> würde es genauso gut tun ...Edit: Nur noch ein Beitrag zum Tausender

-
Falls er genau das angegebene Auto kaufen soll, muss er einen Zeiger benutzen.
Ansonsten kauft er eine Kopie des Autos. (hinzufügen...)
Bsp:class Fahrer { private: Auto *m_pAuto; // ! public: void kaufen(Auto& car) // kauft genau dieses Auto { m_pAuto = &car; } }; class Fahrer { private: Auto m_auto; public: void kaufe(Auto const& car) // kauft eine Kopie { m_auto = car; } };
-
Ist es schlimm das da eine Kopie drin steckt.
Ist immer noch das selbe Auto mit den selben Eigenschaften.Wieso einen Zeiger benutzen, wo keiner gebraucht wird.
Dir ist klar das dein Zeiger ungültig wird, sobald das übergebene Argument seinen Gültigkeitsbereich verliert ...Zudem kommt die ganze Zeigersyntax hinzu ( derefernzieren etc. ), was IMA unschön und unsauber wirkt.
-
Nur so nebenbei: "auto" (mit kleinem a) ist ein Keyword, und zwar die default storage class für lokale Variablen (die 2. mir bekannte storage class für lokale variablen ist "static").
-
Die Realität lässt sich nunmal nicht immer 100%ig abbilden

Du könntest aber das Auto aufm dem Heap anlegen lassen und als std::auto_ptr übernehmen lassen. Das würde dem Anwender signalisieren, dass du das Auto quasi in deinen Besitz überträgst.class Fahrer { std::auto_ptr<Auto> mein_auto_; }; void Fahrer::kaufe(std::auto_ptr<Auto> mein_neues_auto) // übernimmt den Besitz { mein_auto_ = mein_neues_auto; }Zusätzlich kannst du natürlich noch eine Hilfsfunktion anbieten, damit sich der Anwender nicht um die Details der Erzeugung kümmern muss.
std::auto_ptr<Auto> auto_bauen(/*Eigenschaften des Autos*/) { return auto_ptr<Auto>(new Auto(/*...*/)); }
-
KasF schrieb:
Ist es schlimm das da eine Kopie drin steckt.
Ist immer noch das selbe Auto mit den selben Eigenschaften....Aber nur, solange diese beiden Objekte nicht gändert werden:
struct Auto { bool intakteBremsleitung; Auto() : intakteBremsleitung(true) {} }; class Fahrer { Auto meinAuto; public: gibAuto(Auto a) {meinAuto = a; } void fahrLos() { if(!meinAuto.intakteBremsleitung) throw runtime_error("zu gefährlich"); // ... } }; void zerschneideBremsleitung(Auto& a) { a.intakteBremsleitung = false; } int main() { Auto tollerBMW; Fahrer KasF; KasF.gibAuto(tollerBMW); zerschneideBremsleitung(tollerBMW); KasF.fahrLos(); // -> Boom
Es ist einfach eine Frage der Aufgabenstellung, ob ein Fahrer seine eigene Kopie erhalten soll oder nicht....
Wenn z.B. ein konkretes Auto nur einmal verkauft werden soll (wie im RL üblich), sollte man auch da keine Kopie anlegen.Gruß,
Simon2.
-
hi
vielen dank für eure hilfe!
hat mir echt viel geholfen!aber hier nur mal die nächste "dumme" neuling frage...
wenn ich des jetzt so hab...
fahrer hat die methoden gasgeben und bremsen
auto hat die methoden gasgeben und bremsen
fahrer hat die methode autokaufen (da füg ich, wie ihr mir gezeigt habt, ein auto hinzu)wie gib ich jetzt vernünftig gas?
ich hätte mir des so gedacht, dass ich beim fahrer in der mehtode gasgeben die vom auto objekt aufruf... aber wie man merkt... ich bin echt noch vor den kinderschuhen in dem bereich...
Gruß
peter
-
@DeSoVoDaMu: Wieso benutzt du Zeiger und riskierst so vllt ungültige Objekte ???
Ein list<Auto> würde es genauso gut tun ...Simon2 hat es schon erklaert, wie ich es mir auch gedachte habe. Ein Auto ist einmal vorhanden und dieses wird gekauft, nicht etwa eine Kopie.
Wenn ein Fahrer nicht schon mit einem Auto geboren (->erzeugt) wird (schoene Vorstellung btw ;D), kommt man um Zeiger in der einen oder anderen Form nicht herum (sei es nun direkt ein Zeiger, auto_ptr oder eine Klasse mit Referenzzaehlung [welche zumindest intern Zeiger verwendet]).
Ich wollte (/hatte keine Zeit) hier jetzt ein ganzes Programm zu schreiben
Sollte nur als Denkanstoss dienen, zumal etwas wenig Infos vorhanden waren.Gruss,
DeSoVoDaMuEdit Antwort auf Frage
wie gib ich jetzt vernünftig gas?
ich hätte mir des so gedacht, dass ich beim fahrer in der mehtode gasgeben die vom auto objekt aufruf... aber wie man merkt... ich bin echt noch vor den kinderschuhen in dem bereich...Wenn du es jetzt mit einem Zeiger auf ein Auto gemacht hast (also keine Liste) dann folgender massen:
void Fahrer::Gasgeben() { m_pauto->Gasgeben(); }
-
peterli schrieb:
ich hätte mir des so gedacht, dass ich beim fahrer in der mehtode gasgeben die vom auto objekt aufruf... aber wie man merkt... ich bin echt noch vor den kinderschuhen in dem bereich...

Genauso solltest du es machen (eventuell vorher überprüfen, ob du bereits ein Auto hast):
//basierend auf viande's Ansatz: void Fahrer::gasgeben() { if(mein_auto_.get()==0) cout<<"Isch 'abe gar kein Auto"<<endl; else mein_auto_->gasgeben(); }
-
Simon2 schrieb:
struct Auto { bool intakteBremsleitung; Auto() : intakteBremsleitung(true) {} }; class Fahrer { Auto meinAuto; public: gibAuto(Auto a) {meinAuto = a; } void fahrLos() { if(!meinAuto.intakteBremsleitung) throw runtime_error("zu gefährlich"); // ... } }; void zerschneideBremsleitung(Auto& a) { a.intakteBremsleitung = false; } int main() { Auto tollerBMW; Fahrer KasF; KasF.gibAuto(tollerBMW); zerschneideBremsleitung(tollerBMW); KasF.fahrLos(); // -> BoomSollte es da Boom machen, also eine Exception fliegen ???
( Ich gebe erst auf, wenn ichs verstanden habe, man will ja selber auch was lernen
)
-
KasF schrieb:
...
Sollte es da Boom machen, also eine Exception fliegen ???
...Sagen wir mal so: Es entspricht höchstwahrscheinlich nicht der Erwartung des Programmierers oder Anwenders.
Wenn ich im echten Leben dem BMW, den ich Dir verkauft habe, die Bremsleitungen durchschneide, sollte Deine Prüfung auch ergeben, dass sie durchgeschnitten sind ... und Du nicht losfahren, sonst macht es "Boom".
Gruß,
Simon2.
-
Man bedenke das mit Zeigern die Möglichkeit besteht, dass ein internes Objekt ( Auto ) von meiner Klasse Fahrer, ohne einen Fahrer anzusprechen geändert werden könnte ... ( außnahme auto_ptr }
Naja, ich würde mir ne Klasse Autohandel oder so basteln, die mir nur Autos an Fahrer verkauft, so würde ich nicht direkt selber Autos erstellen und darauf zugreifen können.
class Fahrer { Auto myCar; public: void kaufeAuto ( const Auto& aa) { myCar = aa; } // ... } int main() { Fahrer Simon2; Auto bmw; Simon2.kaufeAuto(bmw); zerschneideBlaBla(bmw); Simon2.drive();Ist doch gut das du noch fahren kannst, schließlich ist das dein Auto und keiner sollte daran rumfuschen können ...
Wie du schon gesagt hattest, es kommt auf die Aufgabenstellung an und wie man es modelliert. Jenachdem muss man sich über sowas dann keine Gedanken machen.
-
KasF schrieb:
Man bedenke das mit Zeigern die Möglichkeit besteht, dass ein internes Objekt ( Auto ) von meiner Klasse Fahrer, ohne einen Fahrer anzusprechen geändert werden könnte ...
Eben DAS sollte mein Beispiel zeigen: Im realen Leben kann es so sein, dass jemand Anderes außerhalb Deiner Kontrolle Zugriff auf Dein Auto hat - soll mein Programm das widerspiegeln, ist eine innere Kopie unpassend und Pointer/Referenz geeigneter.
Gruß,
Simon2.