Zeiger
-
Ich habe mal eine Frage.
Angenommen ich übergebe einen Zeiger auf eine von mir erstellte Klasse (Kostendaten).
class Berechnung ... private: Kostendaten *Kosten; ...Die Klasse Kostendaten hat eigene Methoden und gibt mir Beispielsweise eine map<Haeuser,Straßen> zurückgibt
class Kostendaten ... private: map<Haeuser,Straßen> test; public: map<Haeuser,Straßen> test2 () {return test ;}Warum kann ich denn mit einem Iterator nicht auf die einzelnen Elemente der Map Kostendaten von der Klasse Berechnung aus zugreifen? Da meldet er mir immer einen unbekannten Fehler.
Habe auch schon versucht die Methode alsmap<Haeusern,Straßen> *test2 () {return &test ;}zu definieren
Wenn ich das Ergebnis der Methode nochmal in eine Map in Berechnung kopiere, funktioniert alles tadellos... aber damit mach ich ja den Vorteil von Zeigern zunichte.
map<Haeusern,Straßen> ::iterator itr;
itr=Kosten->test2().begin();// hier meldet er mir den Fehler... wenn ich es Debugge, hat er auch keine Häuser drin
cout<<itr->first.get_Name();
-
gib doch eine referenz zurück...
[cpp]
map<T1, T2>& test2()
{
return this->test;
}
[{cpp]
-
leider habe ich dabei das selbe Problem...
er öffnet jedes Mal die Datei:
dbgheap.c und meldet einen unbekannten Fehlerund Heap ist doch irgendwas mit Speicher
also denke ich das das mit dem Iterator nicht funktioniert
-
Also ein Laufzeitfehler? Kein Wunder bei Spielereien mit Zeigern
.Versuch mal ein kleines Beispielprogramm zu basteln, welches den Fehler zeigt. Der Code den du bis jetzt angegeben hast, reicht nicht um das zu diagnostizieren.
Meine Wette ist natürlich, dass Kosten nicht initialisiert ist.
-
Ich denke, das hat weniger mit dem Iterator als mit dem "Kostendaten"-Zeiger bzw. dem Map-Inhalt zu tun.
Hast du überhaupt für die Variable "Kosten" Speicher reserviert? Und wenn ja, hast du Daten in die Map eingetragen? Weil wenn keine Daten da drin sind, kannst du auch nicht auf den ersten Datensatz (begin()) zugreifen.Muß deine Kosten-Variable überhaupt als Zeiger angelegt sein (d.h. kann diese 'null' sein bzw. möchtest du die Instanz austauschen können)?
-
Kein Problem:
class Haeuser { private: string name; public: Haeuser(string pname) string get_Name() const (return name;) } Haeuser::Haeuser (string pname) { name=pname; }class Kostendaten private: map<Haeuser,Straßen> test; public: map<Haeuser,Straßen> test2 () {return test;}class Berechnung private: Kostendaten *Kosten; public: void bestimme_Kosten();Berechnung::Berechnung(Kostendaten *pKosten) : Kosten(pKosten) { } void Berechnung:bestimme_Kosten() { map<Haeuser,Straßen>:iterator berechnung=Kosten->test2().begin(); //HIER KNALLTS :/ cout<<berechnen->first.get_Name(); }die Variante funktioniert:
void Berechnung:bestimme_Kosten() { map<Haeuser,Straßen> test_1=Kosten->test2(); map<Haeuser,Straßen>:iterator berechnung=test_1.begin(); cout<<berechnen->first.get_Name(); }aber ist doch irgendwie doof, nochmal alles zwischen zu kopieren
-
Jetzt zeig bitte noch, wie du das
BerechnungObjekt erzeugst.
-
ich habe ja am Anfang auch geglaubt, dass ich bloß vergessen habe die Kostendaten zu initialisieren. Wenn ich das Zwischenkopiere funktioniert es aber problemlos... da steht dann auch was in der Map drin... so wie es sein muss

nur dann dachte ich, dann brauch ich keinen Zeiger übergeben, sondern kann gleich die Kostendaten als Kopie übergeben...
//hier liest er ne Menge Werte aus der Datei ein.. die gebe ich dann noch aus, um zu sehen, ob er das macht
Kostendaten test;
test.Kostendaten_einlesen();Berechnung neu(&test);
neu.bestimme_Kosten();
-
Meine Frage ist ja, warum funktioniert die 2. Variante und die 1. nicht? Daten sind ja drin...

-
Das
map<Haeuser,Straßen> test2 () {return test;}gibt auf jeden Fall einen Fehler, wenn du es nicht zwischenspeicherst, da bei jedem Aufruf eine Kopie erzeugt wird. Das
if( k.test2().begin() != k.test2().end() )würde dann z.B. die Iteratoren zweier verschiedener Maps vergleichen.
-
Ich habe ja auch versucht, davon die Adresse oder Referenz zurück zu geben:
map<Haeuser,Straßen> *test2 () {return &test;}
map<Haeuser,Straßen> &test2 () {return test;}
wie kann ich denn sicherstellen, dass ich immer auf das selbe Ergebnis zugreife?
Ich dachte außerdem, ich rufe die Methode ja auch nur einmal auf, ich lege ja den Iterator da drauf oder nicht??
-
Nach dieser Zeile
map<Haeuser,Straßen>:iterator berechnung=Kosten->test2().begin();ist der Iterator auch gelich nicht mehr zu gebrauchen, da die Map nicht mehr existiert.
Mit der Referenz oder dem Pointer müsste es aber funktionieren. Da ist dann noch ein anderer Fehler vorhanden.
-
hm vielleicht muss ich auch noch die Methode in der Klasse Häuser anpassen...
warum ist denn der iterator nicht mehr zu gebrauchen? Damit ich noch was lerne

-
Julia_Prog schrieb:
warum ist denn der iterator nicht mehr zu gebrauchen?
manni66 schrieb:
ist der Iterator auch gelich nicht mehr zu gebrauchen, da die Map nicht mehr existiert
-
Auch wenn ich nicht so wirklich verstanden habe, warum das mit dem Iterator dann nicht mehr funktioniert, läuft jetzt wenigstens das Programm.
Ich danke für die Hilfe.
-
map<Haeuser,Straßen> test2 () {return test;}erzeugt eine Kopie für die rufende Funktion.
Mitmap<Haeuser,Straßen>::iterator berechnung=Kosten->test2().begin();holst Du dir dann einen Iterator auf diese Kopie.
Da Du aber die Kopie nirgendwo ablegst ist sie sofort danach wieder perdu, und dein Iterator zeigt ins Nirvana.Alternative:
map<Haeuser,Straßen> & test2 () {return test;}Und
map<Haeuser,Straßen> &xyz=Kosten->test2(); map<Haeuser,Straßen>::iterator berechnung=xyz.begin();Keine Kopie, kein Zeiger.
Wobei - ich bin mir nicht sicher, ob wir dann nicht wieder über das
private:stolpern. Versuchs halt mal...
-
So wie ich den Code verstehe, sollen die Daten ja nur zur Berechnung ausgelesen werden.
Daher wäre ein Umschreiben des Codes auf "const correctness" sowieso am besten, denn interne Daten sollte man möglichst nicht einfach per "non-const reference" ändern dürfen.Hier also mein Vorschlag:
map<Haeuser,Straßen> my_map; const map<Haeuser,Straßen> & Map () const { return my_map; }Und der Zugriff dann von außen nur über "const_iterator":
const map<Haeuser,Straßen> & xyz = Kosten->Map(); for(map<Haeuser,Straßen>::const_iterator it = xyz.begin(); it != xyz.end; ++it) { // ... }Evtl. noch einen Aliasnamen in der Klasse anlegen, z.B.
typedef map<Haeuser,Straßen> street_map; typedef street_map::const_iterator street_const_iterator;und dann nur noch damit arbeiten.