stl::list und vererbung , eine liste in einer liste ausgeben und zugreifen wie?
-
Ok jetzt wirds krass, ich mute euch jetzt ziemlich viel zu, aber eventuell erbarmt sich einer (jedoch wär ich net böse wenn ich keine antwort erhalte, dafür hab ich schon zuviel hilfe von euch bekommen)
habe hier folgendes.. ich habe eine klasse town und eine abstakte Klasse building und die vererbt, d.h. noch weitere 4 unterklassen hier nur eine angeführt mit namen Marketplace.. Es ist vorgabe das Building abstract ist.
so das coding ://town.h #pragma once #include <string> using std::string; #include <iostream> using std::ostream; using std::endl; using std::cout; #include <list> #include "Building.h" #include <iterator> #include <typeinfo> class Building; class Town { //friend ostream&operator<<(ostream&, const Town const &t); friend ostream& operator<<(ostream& out, Town const* d); protected: std::list<Building*> buildinglist; public: Town(const string& townName); Town(const Town& src);//copyconstructor wg kopieren in liste?! virtual ~Town(void); void setTownName(); void setTownSize (int townSize); void setTownMoney (int townMoney); void setTownResearch (int townResearch); void setTownLuxuryGoods (int townLuxury); string getTownName() const; int getTownSize() const; int getTownMoney() const; int getTownResearch() const; int getTownLuxuryGoods()const; void grow(); void insertBuilding(Building& b); bool operator<(const Town& value) const; void print()const; //ausgabe welche gebäude existieren { std::list<Building*>::const_iterator iter; for(iter=buildinglist.begin(); iter!=buildinglist.end(); ++iter) { cout<<typeid(Building).name(); } //???? //cout<<typeid(Building).name(); //hier gibs nur die adresse aber nicht was für ein gebäude es ist! /*std::ostream_iterator<Building*>output(cout," "); cout<<"Gebaeude:"; std::copy(buildinglist.begin(), buildinglist.end(),output);*/ } private: string makeCompareable(const string& str) const; string name; int size; int money; int research; int luxuryGoods; };//end Class Town inline ostream& operator<<( ostream& out, Town const &t ) { out<<std::left<<"Stadt:\t\t"<<t.getTownName() <<" \nhat groesse:\t"<<t.getTownSize() <<" \nbesitzt:\t"<<t.getTownMoney()<<" Euro." <<" \nund hat:\t"<<t.getTownLuxuryGoods()<<" Luxusgueter." <<" \nund Wissen:\t"<<t.getTownResearch()<<" IQ." <<"\n******************************"<<endl; t.print(); // für die ausgabe welche gebäude existieren /* //nicht möglich da town hmm wie ausgebebn?? std::ostream_iterator<Building*>output(cout, " "); cout<<"Gebaeude:"; std::copy(Town::buildinglist.begin(), Town::buildinglist.end(),output);*/ return out; }#pragma once #include "Town.h" class Town; class Building { public: Building(Town& parent); // Pointer auf die verwaltende Stadt virtual ~Building(void); virtual void improveTown()=0; virtual string getBuildingName()const=0; protected: Town& refTown; };#pragma once #include "building.h" #include "town.h" //class Town; //class Building; class Marketplace : public Building { public: Marketplace(Town&); virtual ~Marketplace(void); virtual void improveTown(); virtual string getBuildingName()const; private: int moneyAdder; protected: string name; };so also das problem ist die ausgabe wenn ich ein town erstelle und dannach ein Building hier nur implementiert "Marketplace" .. .
Vorgehensweise: console
erst "Neue stadt" dann "neues Gebaeude" und dann "Marketplace" und danach alle städte ausgeben ,
soll erscheinen:Stadt: Heidelberg hat grosse: 1 und hat: 1 luxugüter und : 1 IQ *********************** Gebäude : Marketplace //hier können natürlich mehrere gebäude stehen auch mehrere Marketplaces//hier gebe ich bisher nur aus "!class Building" weil ich eben nicht weiss wie ich auf diese liste zugreife und das attribut name von Marketplace zugreife, ich hatte es probiert über die zugriffs_memberfunktion
getBuildingName die abstrakt ist aber das geht nicht.. vielleicht hab ich auch nicht richtig zugegriffen .. also wenn es nicht zuviel verlangt ist.. (ich weiss es ist viel , aber jeder der will darf gerne helfen
) wäre sehr dankbar :))Also zeigt was ihr draufhabt

ps.
wurde editiert auf wunsch das wesentliche, dh. augenmerk auf printfunktionhier der gesamte code zum testen
http://www.icefighters.eu/uk/UK12.rar
-
sten schrieb:
also wenn es nicht zuviel verlangt ist..
Wenn der ganze Code den du gepostet hast wirklich relevant ist, wird das den meisten hier wohl tatsächlich zu viel sein. Ansonsten wäre es weniger unhöflich und auch wesentlich aussichtsreicher wenn du deine Frage noch einmal dementsprechend überarbeiten würdest.
-
gesagt getan

-
Nicht sicher ob ich dich richtig verstehe (du schreibst ein wenig konfus
), aber dies Standardidiom könnte dir weiterhelfen:class Building { public: virtual std::ostream& print( std::ostream& out ) const = 0; }; std::ostream& operator<<( std::ostream& out, Building const* obj ) { return obj->print(out); }
-
Hi sten, ich glaube, du "verzettelst" dich ein bißchen bei deinem Code (und deinen Kenntnissen).
Du hast nämlich einige Programmier- und Designfehler drin.
Versuche einfach jede Klasse erstmal einzeln zu erstellen und zu testen.Du willst im Stream-Operator << (bzw. der Methode Town::print) auf die Gebäude zugreifen.
Das Iterieren ist ja schon richtig, du mußt dann einfach mittels der Iteratorvariablen auf das Element zugreifen.inline ostream& operator<<( ostream& out, Town const &t ) { t.print(); // für die ausgabe welche gebäude existieren // oder folgendes std::ostream_iterator<Building*>output(cout, " "); cout<<"Gebaeude:"; std::copy(t.GetBuildingList().begin(), t.GetBuildingList.end(), output); return out; }Jetzt mußt du nur noch Town::GetBuildingList() sowie den Stream-Operator << für Buildings deklarieren und implementieren.
Oder aber du benutzt Town::print (wobei ich diese Methode entweder printBuildings nennen würde oder aber alle Town-Infos dort ausgeben würde).void print()const; //ausgabe welche gebäude existieren { std::list<Building*>::const_iterator iter; for(iter=buildinglist.begin(); iter!=buildinglist.end(); ++iter) { cout << (*iter)->getBuildingName() << ", "; // diese Methode hattest du ja extra dafür implementiert, also kannst du sie auch benutzen -) } }P.S. typeid().name() gibt dir nur den compilerinternen Namen der Klasse aus (damit fängst du recht wenig an)
Edit: Tippfehler korrigiert
-
(*iter)->getBuildingName() , genau das hat mir gefehlt
*freumir war die schreibweise (*iter) nicht bekannt bzw hab nicht daran gedacht , danke für deine hilfe..
das mit dem typeid war mir schon bewusst gewesen ich wollte das der erstmal überhaupt irgendwas anzeigt. und ja die namenkonventionen muss ich noch ändern die sind nicht aussagekräftig
die restlichen //comments waren ausdruck meiner verzweifelten suche nach der lösung. die du/Ihr mir jetzt gebracht habt.