Zuweisungsoperator überladen
-
Wenn ihr das noch nicht hattet, bin ich nicht sicher, ob dein Prof die Lösung anerkennt (kannst ja nachher erzählen, was er erwartet hat).
Der dynamic_cast dient dazu, quer durch die Vererbungshierarchie umzuwandeln. Der Aufruf versucht, 'other' als eine Unter-Referenz anzusehen. Wenn es wirklich ein Unter-Objekt referenziert, ist alles gut und der normale Zuweisungsoperator wird aufgerufen. Wenn du dort ein Basis-Objekt übergibst, fliegt dir eine bad_cast Exception entgegen.
-
Schmeiß doch ganz kurz google an und such danach.
http://www.google.com/search?q=dynamic_cast&ie=UTF-8&oe=UTF-8
-
Danke dir. Unser Prof ist ist ziemlich locker was das angeht, solange ich erklären kann was genau ich da mache.
In einer anderen Aufgabe habe ich ein ähnliches Problem:
Ich habe eine Klasse TextObjekt die einen Überladenen Zuweisungsoperator enthält, der soweit auch funktioniert:TextObjekt TextObjekt::operator=(const TextObjekt &T){ if(this == &T){ return *this; } else{ fileName_out = "2_Verion_von" + T.fileName_out; fileName_in = T.fileName_in; text = T.text; return *this; } }Aber dann sollen wir eine Funktion schreiben die den Inhalt des Attributs vector<string> text umdreht:
TextObjekt umdrehen(TextObjekt &T){ vector<string> TextBuffer; int i; i = text.size(); while(i--){ TextBuffer.at(i) = text.at(i); cout << "Umgedreht: " << TextBuffer.at(i); } }Jetzt habe ich das Problem, dass bei der Zuweisung in der main T2= umdrehen(T1); der Compiler meckert:
44 C:\Dev-Cpp\bin\10\blatt10_main_c_d_e.cpp no match for 'operator=' in 'T2 = umdrehen(((TextObjekt&)(&T1)))'Hier macht sich dann wieder mein mangelndes Wissen über die Überladung bemerkbar.
-
In der Funktion fehlt aber eindeutig das return-Statement
Und für die technische Seite empfehle ich dir die Funktionen reverse() und reverse_copy() aus der <algorithm>.Was die Fehlermeldung angeht - zeig doch mal etwas mehr Code.
-
Dies ist die ganze Klasse TextObjekt die bisher funktioniert hat(Sorry etwas viel Code). Neu ist nur die Überladung des Zuweisungsoperators ganz unten, der ohne die Funktion umdrehen() (eigene cpp-Datei) auch gefunzt hat:
// textobject.h #include <iostream> #include <fstream> #include <string> #include <vector> #ifndef _TEXTOBJECT_H_ #define _TEXTOBJECT_H_ using namespace std; /*---------------------------------------------------------------------------*/ class TextObjekt{ static int counter; protected: vector<string> text; //Inhalt der Datei string fileName_in; string fileName_out; public: string write_mode; // Default Konstruktor TextObjekt(); // Erzeugt leeses TextObjekt // Konstruktor TextObjekt(char* f_in_name, char* f_out_name); // Kopierkonstruktor TextObjekt(const TextObjekt &kopie); // Destruktor ~TextObjekt(); // Methoden void print_datei(void); void set_in_datei(const char *name_in_datei); void set_out_datei(const char *name_out_datei); string put_string_i(int i); char put_char_zeile_spalte(int zeile, int spalte); void append_string(string new_string); //vector<string> put_text(void); void replace(string new_string, int i); // Ueberladen des Indexoperator string& operator[](int i); TextObjekt operator=(const TextObjekt &T); void print_alles(void); friend void umdrehen(TextObjekt &T); }; int TextObjekt::counter = 0; /*---------------------------------------------------------------------------*/ TextObjekt::TextObjekt(){ fileName_in = "no_in_file"; fileName_out = "no_out_file"; text.clear(); counter ++; cout << "**Defaultkonstruktor TextObjekt**: (" << counter << ")"<< endl; } TextObjekt::TextObjekt(char* f_in_name, char* f_out_name){ text.clear(); fileName_in = string(f_in_name); fileName_out = string(f_out_name); set_in_datei(f_in_name); //set_in_datei(fileName_in.c_str()); counter ++; cout << "**Konstruktor TextObjekt**: (" << counter << ")"<< endl; } TextObjekt::TextObjekt(const TextObjekt &kopie){ //fileName_in = kopie.fileName_in; //fileName_out = kopie.fileName_out; text = kopie.text; text.clear(); fileName_out = "Kopie_von_" + kopie.fileName_out; fileName_in = kopie.fileName_in; counter ++; cout << "**Kopierkonstruktor TextObjekt**: (" << counter << ")" << endl; } TextObjekt::~TextObjekt(){ if(strcmp(fileName_out.c_str(),"no_out_file") == true){ set_out_datei(fileName_out.c_str()); } counter --; cout << "**Destruktor TextObjekt**: (" << counter << ")" << endl; } void TextObjekt::print_datei(void){ for(int i=0; i<text.size(); i++){ cout << text.at(i) << endl; } } // Datei einlesen void TextObjekt::set_in_datei(const char *name_in_datei){ // Datei nur zum Lesen oeffnen ifstream fin; string buffer2; fileName_in = string(name_in_datei); //string erzeugen text.clear(); // Loescht alle Elemente fin.open(fileName_in.c_str()); // formatiert den Dateinamen in ein Zeichenkette-Format if(!fin){ cout << "Konnte Datei nicht oeffnen!" << endl; } else { while(getline(fin, buffer2)){ // Inhalt einlesen text.push_back(buffer2); } } fin.close(); } void TextObjekt::set_out_datei(const char *name_out_datei){ //Datei zum Schreiben oeffnen fstream fout; fileName_out = string(name_out_datei); if(write_mode != "out"){ ofstream foutapp(fileName_out.c_str(),ios::app); if(!foutapp){ cout << "Feherhaft geoeffnete Datei" << endl; return; } for(int i = 0 ; i < text.size() ; i++){ foutapp << text.at(i)<<endl; } foutapp.close(); } else{ ofstream fout(fileName_out.c_str()); if(!fout){ cout << "Feherhaft geoeffnete Datei" << endl; return; } for(int i = 0 ; i < text.size() ; i++){ fout << text.at(i)<<endl; } fout.close(); } cout << "Datei gespeichert in: " << fileName_out << endl; /*fout.open(fileName_out.c_str()); // formatiert den Dateinamen in ein Zeichenkette-Format if(fout.good()){ for(int i=0; i<text.size(); i++){ fout << text.at(i) << endl; // in Filestream speichern } cout << "Datei gespeichert in Datei: " << fileName_out << endl; fout.close(); } else { cout << "Konnte Datei nicht oeffnen!" << endl; }*/ } string TextObjekt::put_string_i(int i){ if(text.size() > i) // genug Zeilen vorhanden? return text.at(i-1); else return "Zeile nicht vorhanden"; } char TextObjekt::put_char_zeile_spalte(int zeile, int spalte){ if(text.size() > zeile && text.at(zeile-1).size() > spalte && zeile >= 0 && spalte >= 0){ return text.at(zeile-1).at(spalte-1); } cout << "exestiert nicht" << endl; return '\0'; } // String anhaengen void TextObjekt::append_string(string new_string){ text.push_back(new_string); // new_string an text haengen } void TextObjekt::replace(string new_string, int i){ if(text.size() > i) // genug Zeilen vorhanden? text[i-1]=new_string; else cout << "Zeile nicht vorhanden!" << endl; } string& TextObjekt::operator[](int i){ if((i>=0) && (i<text.size())){ return text[i]; } else cout << "?" << endl; } TextObjekt TextObjekt::operator=(const TextObjekt &T){ if(this == &T){ return *this; } else{ fileName_out = "2_Verion_von_" + T.fileName_out; fileName_in = T.fileName_in; text = T.text; return *this; } } void TextObjekt::print_alles(void){ cout << "File_out_name: " << fileName_out << endl; cout << "File_in_name: " << fileName_in << endl; } #endif
-
Interessanter ist im Moment eher die main()-Funktion.
Und wie gesagt: in der umdrehen() fehlt eine return-Anweisung (oder soll der Compiler erraten, was er zurückgeben soll?).
-
Lol nee, also return T;
In der main steht nicht viel drin.int main(){ int a = 0; TextObjekt T1("kurzes_gedicht.txt","machmichnichtkaputt.txt"), T2; // Ausgabe des Inhalts: cout << endl << "Ausgabe T1 vor dem Aufruf der Funktion:" << endl << endl; T1.print_datei(); cout << endl << "Ausgabe T2 vor dem Aufruf der Funktion:" << endl << endl; T2.print_datei(); T1.set_out_datei("machmichnichtkaputt.txt"); // umdrehen von T1: T2= umdrehen(T1); cin >> a; cout << "Ende main ! " << endl; return 0; }
-
Mit dem Inhalt der Funktion mußt du dich nochmal genauer beschäftigen - du packst den vector-Inhalt rückwärts in eine lokale Variable und gibt dann deinen Urprungszustand zurück.
-
Um ehrlich zu sein hab ich mir bei der Funktion keine großartigen Gedanken gemacht, wie man sieht. Hab das ganze Wochenende nur Aufgaben in C++ für morgen gelöst und nu geht nix mehr.
Wenn ich also ein bischen nachdenke müsste ich doch so der Sache ein bischen näher kommen:
TextObjekt umdrehen(TextObjekt &T){ int i; i = text.size(); while(i--){ text.at((text.size())-i) = text.at(i); cout << "Umgedreht: " << text.at(i); } return T; }
-
Wenn du beabsichtigst, die Daten im Ursprungsobjekt umzudrehen, geht es in die richtige Richtung. Aber dabei zerhaust du dir leider dein Array, weil du Teile überschreibst, bevor sie gelesen werden.
TextObjekt umdrehen(TextObjekt &T) { TextObjekt T2 = T; reverse(T2.text.begin(),T2.text.end()); return T2; }Was die Funktion macht, kannst du selber herausfinden

-
Aber was hat es mit der Fehlermedlung auf sich? Ich habe doch einen überladenen Zuweisungsoperator. Oder ist der auch falsch? Oder muss es für jede Operation einen eigenen geben? Ich check das mit dem Überladen irgendwie net.
sorry für meine lange Leitung gestern.
Gruß Dominika44 C:\Dev-Cpp\bin\10\blatt10_main_c_d_e.cpp no match for 'operator=' in 'T2 = umdrehen(((TextObjekt&)(&T1)))'