Probleme mit friend Deklaration
-
Hallo
ich moechte einen istream iterator fuer meine Klasse schreiben. Dabei wollte ich ihn als friend deklarieren. Allerdings bekomme ich viele Fehlermeldungen, wenn ich friend vor meine Deklaration schreibe. Lasse ich friend weg fallen auch die fehlermeldungen weg. Allerdings braeuchte ich die friend Deklaration da ich auf meine private Member zugreifen sollte im Falle des globalen istream operators.
istream methode meiner point klasse:
friend istream& PointN::operator>>(istream& in) { int iDim = getDim(); for(int i = 0; i < iDim; i++) in >> data[i]; return in; }globaler istream operator:
istream& operator>>(istream& in, PointN& p) { if( !p.data ) { p.data = new double[3]; p.dim = 3; } int iDim = p.getDim(); for(int i = 0; i < iDim; i++) in >> p[i]; return in; }Die Fehlermeldungen dazu lauten unter anderem:
error C2805: binary 'operator >>' has too few parameters
error C2248: 'PointN::data' : cannot access private member declared in class 'PointN'woran liegt das? Sorry, mit streams steh ich noch etwas auf Kriegsfuss
-
Du hast das friend an der falschen Stelle hingesetzt - die erste Funktion ist ein Member deiner Klasse und benötigt deshalb kein friend (und hat die falsche Operator-Anordnung für die üblichen Ein/Ausgabe-Operatoren), die zweite Funktion ist KEIN friend.
Richtig wäre es so:class PointN { public: ... friend istream& operator>>(istream& in,PointN& p); ... }; istream& operator>>(istream& in,PontN& p) { if( !p.data ) { p.data = new double[3]; p.dim = 3; } int iDim = p.getDim(); for(int i = 0; i < iDim; i++) in >> p[i]; return in; }
-
Das verstehe ich so nicht. In meiner Point Klasse muss ich doch nicht zusaetzlich noch ein Point Objekt uebergeben. Und was bedeutet falsche Operator Anordnung?
Jetzt bekomme ich folgende Fehlermeldung:
error C2039: '>>' : is not a member of 'PointN'Aber ich habe doch den operator in PointN deklariert und definiert, wieso erkennt er das denn nicht?
class PointN { friend istream& operator>>(istream&, PointN&); }PointN cpp:
istream& PointN::operator>>(istream& in, PointN& p) { int iDim = p.getDim(); for(int i = 0; i < iDim; i++) in >> p[i]; return in; }
-
samo schrieb:
Das verstehe ich so nicht. In meiner Point Klasse muss ich doch nicht zusaetzlich noch ein Point Objekt uebergeben.
]Mit friend wird dem Compiler gesagt, daß die nachfolgende Deklaration keine Memberfunktion deiner Klasse ist, aber trotzdem besondere Zugriffsrechte bekommen soll.
Und was bedeutet falsche Operator Anordnung?
Das bedeutet, dein PointN::operator>>() müsste so aufgerufen werden:
PointN p; p>>cin;(das ist zwar machbar, entspricht aber nicht ganz der "üblichen" Schreibweise)
Jetzt bekomme ich folgende Fehlermeldung:
error C2039: '>>' : is not a member of 'PointN'Aber ich habe doch den operator in PointN deklariert und definiert, wieso erkennt er das denn nicht?
Der Operator ist "nur" ein Freund der PointN-Klasse, keine Memberfunktion - also kannst du bei der Definition das "PointN::" weglassen.
-
dankeschoen, der istream_iterator scheint soweit zu funktionieren. Aber jetzt stuerzt mein Programm an dieser Stelle hier ab:
istream_iterator<PointN> begin(file); // Anfangsiterator auf die Datei istream_iterator<PointN> end; // Enditerator copy(begin,end,back_inserter(vBasePoints));und zwar mit der assertion :
Expression: _BLOCK_TYPE_IS_VALID
und wenn ich dann retry mache stoert er sich an meinem destructor der point-klasse
PointN::~PointN(void) { if(data != NULL) { delete [] data; data = NULL; dim = 0; } }Stimmt dann etwas ad der allocierung im istream operator noch nicht oder hat das einen anderen grund?
-
Ich vermute eher ein Problem mit dem back_inserter und dem Copy-Construktor deiner Klasse (hast du überhaupt einen?). Geh doch mal im Call-Stack eine Ebene nach oben, um zu sehen, von wo aus der Destruktor aufgerufen wird.
(btw, am Ende des Dtor's ist dein Objekt eh hin, da brauchst du nicht noch extra die Membervariablen auf 0 zurücksetzen)
-
er stuerzt am ende der copy funktion ab, wenn er alle punkte eingelesen hat. ich denke das haengt mit der zerstoerung der istream operatoren zusammen. ich habe eine copy funktion fuer die point klasse
PointN::PointN(const PointN &rhs) { dim = rhs.dim; if (dim>0) { data = new double[dim]; for (int i=0;i<dim;i++) data[i]=rhs.data[i]; } invalid = false; }die bis jetzt auch gute dienste geleistet hat

-
Hast du auch einen Zuweisungsoperator in deiner Klasse (sicher ist sicher - ich frag lieber mal nach)?
-
ja hab ich auch
PointN& PointN::operator=(const PointN &rhs) { dim = rhs.dim; if (dim > 0) { data = new double[dim]; for (int i = 0; i < dim; i++) data[i] = rhs.data[i]; } invalid = false; return(*this); }Mir scheint dass bei der Zerstoerung der iteratoren irgendetwas schief laeuft. koennte das nicht sein?
-
Mir scheint zunächst, daß dein Zuweisungsoperator noch eine Absicherung gegen Selbstzuweisung benötigen könnte. (obwohl das in deinem Zusammenhang eher unwahrscheinlich ist).
Nur mal zum Test: Kannst du mal in alle Con- und Destruktoren eine Debug-Ausgabe einbauen, um zu überprüfen, wann und wo sie aufgerufen werden?
-
in der copy methode wird am schluss zweimal der destructor der point methode aufgerufen, ich nehme an fuer jeden iterator (einmal fuer begin, einmal fuer end). beim loeschen des end iterators stuerzt das programm mit der assertion ab.