Matrixeingabe duch Operatorüberladung
-
HI,
ich versuche gerade durch Überladung des << Operators eine Matrix zu befüllen.
Meine Matrix möchte ich aus (Container-Klasse) vector zusammenbauen. Dafür hab ich mir gedacht einen vector als Spaltenvektor mit der Startadresse der jeweiligen Zeilenvektoren zu belegen.Mein Prototyp:
matrix::operator << (matrix &m1, int zahl){}Hierbei stoße ich aber auf das Problem das nach aufruf des Operators dieser ja nicht mehr weiß, dass nun im ersten Index des Zeilenvektors schon ein Wert liegt. Beim zweiten Aufruf würde er diesen ja überschreiben.
Weiß echt nicht mehr weiter.
Danke für Hilfe!
-
Mach es doch so, dass die Funktion (respektive der Operator) bei jedem Aufruf ein
push_back()ausführt, sodass am Ende des Zeilenvektors ein Element drangehängt wird.Was mir jedoch unverständlich ist: Wie willst du mit dem Operator wissen, in welche Zeile er schreiben soll? Das linke Argument ist ja nur die ganze Matrix...
-
Du bringst es auf den Punkt ;). Das mit dem Pushback ist mir auch schon aufgefallen. Man bräuchte am Ende eine Abruchbedingung um in die nächste Zeile zu springen. Nur da häng ich schon seit ner halben Stunde dran.
-
Streetdevil schrieb:
Man bräuchte am Ende eine Abruchbedingung um in die nächste Zeile zu springen. Nur da häng ich schon seit ner halben Stunde dran.
Du meinst sowas?
matrix m; m << 5 << 4 << 3 << newline << 5 << 7 << 8;Definiere für newline (o.ä.) einen eigenen Typen (kann ein leeres Struct sein) und definiere eine neue überladene Operator-Funktion, die dem Objekt mittteilt, dass in eine neue Zeile gewechselt werden soll. Also analog wie bei ostream mit endl.
-
Danke das war eine sehr gute Idee. Hab es mal versucht umzusetzen, nur leider stoße ich beim compilieren auf Fehler die ich nicht deuten kann.
Mein Code:
Matrix.h
#include<iostream> #include<vector> using namespace std; struct newline{}; class matrix { private: vector<int> vector_Y; int index; public: matrix(void); ~matrix(void); matrix operator<<(const matrix AUSG_MATRIX); operator >> (matrix eing_matrix,const int WERT); operator >> (matrix eing_matrix,const newline N); }Matrix.cpp
#include<iostream> #include<vector> #include "matrix.h" matrix::matrix(void){ vector_Y[0] = new vector<int>; index=0; } matrix::operator >> (matrix &eing_matrix, const signed int WERT){ eing_matrix.*(vector_Y[index]).pushback(WERT); } matrix::operator >> (matrix &eing_matrix, newline N){ eing_matrix.vector_Y.pushback(new vector<int>); index++; }main.cpp
#include<iostream> #include"matrix.h" ;using namespace std; int main(void){ matrix m1; newline endl; m1>>2>>3>>endl; }(17)error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt. (17)error C2804: Binärer Operator '>>' hat zu viele Parameter (18)error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt. (18)error C2804: Binärer Operator '>>' hat zu viele Parameter (11)error C2676: Binärer Operator '>>': 'matrix' definiert diesen Operator oder eine Konvertierung in einen für den vordefinierten Operator geeigneten Typ nicht (12)error C2676: Binärer Operator '>>': 'matrix' definiert diesen Operator oder eine Konvertierung in einen für den vordefinierten Operator geeigneten Typ nicht (13)error C2676: Binärer Operator '>>': 'matrix' definiert diesen Operator oder eine Konvertierung in einen für den vordefinierten Operator geeigneten Typ nichtWäre schön wenn mir da einer weiterhelfen könnte.
-
Dem Operator musst du nur ein Argument übergeben, nämlich das der anzuhängenden Zahl.
-
Wie wäre es mit einem standardisierten Format, wie
[¢ode][ 1, 2, 3;
4, 5, 6;
7, 8, 9 ][/code]??
-
Standard??? schrieb:
Wie wäre es mit einem standardisierten Format, wie
[ 1, 2, 3; 4, 5, 6; 7, 8, 9 ]??
Wie willst du das anstellen? Du kannst ; nicht überladen, und die []-Klammern glaube ich in diesem Kontext auch nicht... Oder Übergabe als String?
-
Standard??? schrieb:
Wie wäre es mit einem standardisierten Format, wie
[¢ode][ 1, 2, 3;
4, 5, 6;
7, 8, 9 ][/code]??Das wäre natürlich schöner. Aber es ist Vorgabe den Operator >> zum Überladen für die Eingabe zu verwenden.
Ich hab das jetzt mal richtig gemacht ;).
Mein Code:
matrix.h
struct newline{}; class matrix { private: vector<int> vector_Y; int index; public: matrix(void); //~matrix(void); //matrix operator<<(const matrix AUSG_MATRIX); matrix operator >> (const int WERT); matrix operator >> (const newline N); }matrix.cpp
matrix::matrix(void){ vector_Y[0] = new vector<int>; index=0; } matrix matrix::operator >> (const signed int WERT){ *(vector_Y[index]).pushback(WERT); } matrix matrix::operator >> (const newline N){ vector_Y.pushback(new vector<int>); index++; }Hier bekomm ich aber 3 Linker Fehler mit denen ich nicht ganz klar komme.
error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: class matrix __thiscall matrix::operator>>(struct newline)" (??5matrix@@QAE?AV0@Unewline@@@Z)" in Funktion "_main". error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: class matrix __thiscall matrix::operator>>(int)" (??5matrix@@QAE?AV0@H@Z)" in Funktion "_main". error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: __thiscall matrix::matrix(void)" (??0matrix@@QAE@XZ)" in Funktion "_main".Ich verwende Microsoft Visual C++ 2008 Express Edition.
-
Da fehlt doch ein Semikolon am Ende der matrix-Deklaration.
-
Stímmt, danke. Hat aber nicht bei den Linker Fehlern geholfen.
-
Ohne die main-Funktion jetzt gesehen zu haben, gehe ich schwer davon aus, dass du den <<-Operator falsch implementiert hast.
Ein möglicher (Pseudo-)Aufruf von
Matrix m; m << 1 << 2 << newline() << 3 << 4;solltest du mit Referenzen realisieren. Der Operator << muss dabei global überladen sein und nicht als Methode realisiert werden (analog dazu sieh dir mal an, wie man die Operator << für Streams - ostream, istream überlädt).
Matrix& operator<<(Matrix&, int); Matrix& operator<<(Matrix&, ManipulatorType const&);Weiterhin wäre zu überlegen, ob du nicht deine Matrix-Klasse zunächst ohne derartigen "SchnickSchnack" realisieren solltest. Die Datenerfassung via Operator << könntest du in einer MatrixBuffer oder MatrixStream-Klasse vornehmen.
Grüße... Heiko
-
Meine main sieht wie folgt aus:
#include <iostream> #include "matrix.h" using namespace std; int main(void){ matrix m1; newline endl; m1>>2; m1>>3; m1>>endl; }So müsste das ja eigentlich funktionieren. Bleiben halt nur diese komischen Linker Fehler.
-
Hm, ich habe gerade festgestellt solange ich den Operator in der Main nicht verwende kommen auch nicht diese Linker Fehler. Doch sobald ich zum Beispiel m>>1; schreibe sind sie wieder da? Woran kann das nur liegen? Steh grad wirklich ein wenig aufm Schlauch.
Hätte mal noch einige andere Fragen(stehen im Quelltext):
matrix.cpp
matrix::matrix(void){ vector_Y[0] = new vector<int>; //Kann ich so überhaupt dem vektor_y als Wert die Adresse meine Zeilenvektors zuweisen? index=0; } matrix matrix::operator >> (const signed int WERT){ *(vector_Y[index]).push_back(WERT); //Hier versuche ich den Zeiger im vektor_Y zu derefereenziern um so auf den Zeilenvektor zuzugreifen. Mach ich da vielleicht was falsch? } matrix matrix::operator >> (const newline N){ vector_Y.push_back(new vector<int>); //Und hier möchte ich einen neuen Zeilenvektor (also die Adresse) als neuen Wert in den Spaltenvektor vektor_Y schreiben. Geht das so? index++; }Mein ganzer Quelltext:
main.cpp
#include <iostream> #include "Matrix.h" using namespace std; int main(void) { matrix m; newline endl; m>>2; m>>3; m>>endl; return 0; }Matrix.h
#include<iostream> #include<vector> using namespace std; struct newline{}; class matrix { private: vector<int> vector_Y; int index; public: matrix(void); //~matrix(void); //matrix operator<<(const matrix AUSG_MATRIX); matrix operator >> (const int WERT); matrix operator >> (const newline N); };Matrix.cpp
#include <iostream> #include <vector> #include "Matrix.h" matrix::matrix(void){ vector_Y[0] = new vector<int>; index=0; } matrix matrix::operator >> (const signed int WERT){ *(vector_Y[index]).push_back(WERT); } matrix matrix::operator >> (const newline N){ vector_Y.push_back(new vector<int>); index++; }
-
Vielleicht solltest du uns mal den vollständigen Code zeigen, den du tatsächlich versuchst zu kompilieren und zu linken.
-
So hab das jetzt alles mal umgeschrieben und denke das müsste jetzt eigentlich so passen. Aber ich bekomme beim Aufruf des >> Operators immer eine Zugriffsverletzung die ich mir nicht ganz erklären kann.
Mein Code:
main.cpp
#include <iostream> #include "Matrix.h" using namespace std; int main(int argc, char *argv[]) { P_matrix m; newline endl; m>>2; m>>3; system("PAUSE"); return EXIT_SUCCESS; }Matrix.h
#include <iostream> #include <vector> using namespace std; struct newline{}; class P_matrix { private: vector<vector<int> > mv; int index; public: P_matrix(void); //~matrix(void); // P_matrix operator << (const P_matrix &AUSG_MATRIX); P_matrix operator >> (const int WERT); P_matrix operator >> (const struct newline N); };Matrix.cpp
#include <iostream> #include <vector> #include "Matrix.h" using namespace std; P_matrix::P_matrix(void){ mv.push_back(vector<int>()); index=0; } P_matrix P_matrix::operator >> (const int WERT) { mv[index].push_back(WERT); } P_matrix P_matrix::operator >> (const struct newline N) { mv.push_back(vector<int>()); index++; }Die Zugriffsverletzung kommt bei m>>2 in der main.
-
Ich sehe keine return-Anweisungen.
-
Ach stimmt.
Mit
return *this;klappt das dann auch. Vielen Dank.
-
Versuche mich gerade noch an der Ausgabe. Das mache ich indem ich den Operator << überlade.
Mein Code:
matrix.h
#include <iostream> #include <vector> using namespace std; struct newline{}; class P_matrix { private: vector<vector<int> > mv; int index; public: P_matrix(void); //~matrix(void); P_matrix operator << (const P_matrix &AUSG_MATRIX); P_matrix operator >> (const int WERT); P_matrix operator >> (const struct newline N); friend ostream & operator<<(ostream & os, const P_matrix &m); };matrix.cpp
#include <iostream> #include <vector> #include "Matrix.h" using namespace std; P_matrix::P_matrix(void){ mv.push_back(vector<int>()); index=0; } P_matrix P_matrix::operator >> (const int WERT) { mv[index].push_back(WERT); return *this; } P_matrix P_matrix::operator >> (const struct newline N) { mv.push_back(vector<int>()); index++; return *this; } ostream & operator<<(ostream & os, const P_matrix m){ int i, j; for (i=0; i<m.mv.size();i++) { j=0; for (j=0; j<m.mv[i].size();j++) { os<<m.mv[i][j]<<" "; j++; } os<<endl; i++; } return os; }Heibei bekomme ich aber beim kompilieren immer die Nachricht:
11 `std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > P_matrix::mv' is privateIch dachte wenn man eine externe Funktion als friend aufnimmt kann diese auch auf die privaten Daten der Klasse zugreifen?
-
Streetdevil schrieb:
Ich dachte wenn man eine externe Funktion als friend aufnimmt kann diese auch auf die privaten Daten der Klasse zugreifen?
Stimmt, aber das hasst du nicht getan. Der Typ der Funktion, die als friend deklariert wurde, stimmt nicht mit der Funktion überein, die definiert wurde.
Übrigens hasst du - gegenüber dem Stil der IO-Streams - die Bedeutung der Operatoren << und >> vertauscht. Die Richtung der Pfeile sollte anzeigen, wohin Information übertragen werden. Mithin dient << der Datenausgabe (stream steht links, mithin werden Daten in den Stream übertragen) und >> der Dateneingabe (die Daten werden aus dem Stream in die Variablen geschoben). Bei dir ist es - sinngemäß - genau anders herum.