Klasse
-
Hallo zusammen, ich weis ich habe die Frage schon einmal gestellt und auch tolle Antworten bekommen, aber mir hat man meinen Laptop geklaut, auf dem ich den Link gespeiert habe und hier kann ich den nicht mehr finden.
Folgendes: ich habe folgende Klasse gegeben ( man hat mir hier auch schon gesagt, dass das Programmiertechnisch nicht ganz korrekt ist, aber ich muss genau damit arbeiten)
#include <assert.h> #include <iostream> #include <cmath> using namespace std; class vektor { public: int dim; double *v; // Konstruktor, erwartet Dimension als Argument // z.b. vektor x(3), y(5), z(3); // v = new vektor(4); vektor(unsigned int l) { dim=l; if(l > 0) v = new double[l]; else v = NULL; }; double norm() { double sqnorm = 0.0; for (unsigned int i = 0; i < dim; i++) { sqnorm = sqnorm + v[i]*v[i]; } return sqrt(sqnorm); } vektor operator+(const vektor& v2) { assert (dim == v2.dim); vektor *newv= new vektor(dim); for (unsigned int i = 0; i<dim; i++) { newv->v[i] = v[i] + v2.v[i]; } return *newv; } vektor operator-(const vektor& v2) { assert (dim == v2.dim); vektor *newv= new vektor(dim); for (unsigned int i = 0; i<dim; i++) { newv->v[i] = v[i] - v2.v[i]; } return *newv; } // Punktprodukt vektor * vektor double operator*(const vektor& v2) const { assert ( dim == v2.dim ); double s= 0.0; for (unsigned int i = 0; i<dim; i++) { s= s + v[i] * v2.v[i]; } return s; } // Praedikat bool colinear(const vektor&); // vektor * scalar vektor& operator*(double scalar) { vektor *newv= new vektor(dim); for (unsigned int i = 0; i<dim; i++) { newv->v[i] = v[i] * scalar; } return *newv; } // Wie indizierter Array Zugriff, schreibend und lesend double& operator[](int index) { assert (index >=0); assert (index < dim); return v[index]; } vektor& resize(int k) { int i; vektor *newv = new vektor(k); for(i = 0; i < fmin(this->dim, k); i++) { newv->v[i] = this->v[i]; } for(; i < k; i++) { newv->v[i] = 0; } return *newv; } }; // output mittels iostream // Kann keine Methode von vektor sein, weil der erste // Operand kein vektor ist. ostream& operator<<(ostream& left, vektor& right) { for(unsigned int i=0; i < right.dim; i++) { left << right.v[i] << " "; } return left; } int main() { vektor X(3); X.v[1] = 3; X.v[2] = 2; X.v[3] = 4; vektor Y(3); Y.v[1] = 1; Y.v[2] = 2; Y.v[3] = 1; cout << X.operator-(&Y)<< endl; system("PAUSE"); return 0; }nun habe ich versucht, den minus operator aufzurufen und die beiden Vektoren zu subtrahieren.
Ich weis leider echt nicht wie der Code an der Stellecout << X.operator-(&Y)<< endl;und die ganze main Funktion aussehen muss dass zum Schluss das Ergebnis 2, 0, 3 herauskommt.
Vielen Dank für eure Hilfe
-
Hallo jeffry,
Du kannst die Signatur in
ostream& operator<<(ostream& left, const vektor& right);ändern.
Dann noch die Indizes 0,1,2 bei den Zuweisungen verwenden und
du hast die Ausgabe, die du möchtest.Allerdings hat dein Programm noch Memory-Leaks... Zu jedem new gehört ein delete!
Außerdem solltest du den Copy-Construktor definieren, wenn du dynamisch Speicher allokierst.Gruß,
XSpilleEDIT:
Achso:
cout << X.operator-(Y)<< endl;bzw.
cout << X-Y<< endl;
-
Hallo XSpille,
vielen Dank, funktioniert perfekt.
Kannst du mir vllt noch sagen, warum dsas nur mit dem const bei der Signatur funktioniert und was die Signatur genau macht.Das mit den Memory Leaks hat man mir schon mal gesagt, aber das kommt vom Prof.
Allerdings ist es Programmieren für Mathematiker, also nicht so streng sehen, wie bei einer Info-Vorlesung.Diese Stellen sind mir auch noch nicht ganz klar.
hier wird der Konstruktor erzeugt, für was man den hier braucht, leuchtet mir auch nicht ganz ein, würde es auch mit einem array funktionieren?
vektor(unsigned int l) { dim=l; if(l > 0) v = new double[l]; else v = NULL; };wir haben diese methode:
vektor operator-(const vektor& v2) { assert (dim == v2.dim); vektor *newv= new vektor(dim); for (unsigned int i = 0; i<dim; i++) { newv->v[i] = v[i] - v2.v[i]; } return *newv;was wird mit dieser Stelle bezweckt?
vektor *newv= new vektor(dim);wieso brauche ich hier das new -> v[i]?
newv->v[i] = v[i] - v2.v[i];nochmals vielen Dank für eure Hilfe.
VG
-
jeffry schrieb:
Hallo XSpille,
vielen Dank, funktioniert perfekt.
Kannst du mir vllt noch sagen, warum dsas nur mit dem const bei der Signatur funktioniert und was die Signatur genau macht.Also das const garantiert dir, dass du auf dem Objekt nur const-Funktionen machen kannst und keine verändernden Operationen auf die Klassen-Member.
Also es ist so, weil man nicht (versehentlich) Veränderungen auf temporären Objekten hat.
http://stackoverflow.com/questions/1565600/how-come-a-non-const-reference-cannot-bind-to-a-temporary-objectWenn du
vektor operator-(const vektor& v2)hast, dann ist dein Vektor nur temporär. Er wird dann meistens durch den Zuweisungsoperator oder Copy-Constructor kopiert.
Da dein Objekt in deinem Fall danach nicht mehr verwendbar ist, ist es quasi ein Schutz, dass du nicht etwas modifizierst, was eh keinen Effekt hat.
Wenn du die Signatur in
ostream& operator<<(ostream& left, vektor right);
ändern würdest, dann würde beim Funktionsaufruf eine Kopie erstellt und es
würde (mit unnötiger Kopie) auch funktionieren.
Deswegen auch der Hinweis, den Copy-Constructor und Zuweisungsoperator zu implementieren. (Insbesondere, wenn du die Memory-Leaks fixt)jeffry schrieb:
Das mit den Memory Leaks hat man mir schon mal gesagt, aber das kommt vom Prof.
Allerdings ist es Programmieren für Mathematiker, also nicht so streng sehen, wie bei einer Info-Vorlesung.Diese Stellen sind mir auch noch nicht ganz klar.
hier wird der Konstruktor erzeugt, für was man den hier braucht, leuchtet mir auch nicht ganz ein, würde es auch mit einem array funktionieren?
vektor(unsigned int l) { dim=l; if(l > 0) v = new double[l]; else v = NULL; };Jain, dann kannst du aber keine Member-Funktionen verwenden und du würdest
für die (mathematischen) Operatoren freie Funktionen benötigen. Diese müssten dann Templates sein, da du anhand des Arrays nicht feststellen kannst, wie groß es ist. Deswagen wird von C++ i. d. R. auch std::vector verwendet, der quasi nicht anderes macht als ein (vergrößerbares) Array mit einigen Funktionen zur VErfügung zu stellen.jeffry schrieb:
wir haben diese methode:
vektor operator-(const vektor& v2) { assert (dim == v2.dim); vektor *newv= new vektor(dim); for (unsigned int i = 0; i<dim; i++) { newv->v[i] = v[i] - v2.v[i]; } return *newv;was wird mit dieser Stelle bezweckt?
vektor *newv= new vektor(dim);Du erstellst ein neues Objekt auf dem Heap.
Ich würde es so auf dem Stack erstellen, da es eh kopiert wird,
beim Verlassen der Funktion.vektor operator-(const vektor& v2) { assert (dim == v2.dim); vektor newv(dim); for (unsigned int i = 0; i<dim; i++) { newv.v[i] = v[i] - v2.v[i]; } return newv; }jeffry schrieb:
wieso brauche ich hier das new -> v[i]?
newv->v[i] = v[i] - v2.v[i];weil du einen Zeiger auf ein Objekt hast.
jeffry schrieb:
nochmals vielen Dank für eure Hilfe.
VG
-
Super, versteh ich!
vektor operator-(const vektor& v2) { assert (dim == v2.dim); vektor newv(dim); for (unsigned int i = 0; i<dim; i++) { newv.v[i] = v[i] - v2.v[i]; } return newv; }das ist mir viel logischer!
Ich hoffe ich nerve nicht, aber ich hätte nochmal eine Frage:
WIr haben folgende Aufgabe zum Üben für die Klausur bekommen.#include <assert.h> #include <iostream> #include <cmath> using namespace std; class vektor { public: int dim; double *v; // Konstruktor, erwartet Dimension als Argument // z.b. vektor x(3), y(5), z(3); // v = new vektor(4); vektor(unsigned int l) { dim=l; if(l > 0) v = new double[l]; else v = NULL; }; double norm() { double sqnorm = 0.0; for (unsigned int i = 0; i < dim; i++) { sqnorm = sqnorm + v[i]*v[i]; } return sqrt(sqnorm); } vektor operator+(const vektor& v2) { assert (dim == v2.dim); vektor *newv= new vektor(dim); for (unsigned int i = 0; i<dim; i++) { newv->v[i] = v[i] + v2.v[i]; } return *newv; } vektor operator-(const vektor& v2) { assert (dim == v2.dim); vektor *newv= new vektor(dim); for (unsigned int i = 0; i<dim; i++) { newv->v[i] = v[i] - v2.v[i]; } return *newv; } // Punktprodukt vektor * vektor double operator*(const vektor& v2) const { assert ( dim == v2.dim ); double s= 0.0; for (unsigned int i = 0; i<dim; i++) { s= s + v[i] * v2.v[i]; } return s; } // Praedikat bool colinear(const vektor&); // vektor * scalar vektor& operator*(double scalar) { vektor *newv= new vektor(dim); for (unsigned int i = 0; i<dim; i++) { newv->v[i] = v[i] * scalar; } return *newv; } // Wie indizierter Array Zugriff, schreibend und lesend double& operator[](int index) { assert (index >=0); assert (index < dim); return v[index]; } vektor& resize(int k) { int i; vektor *newv = new vektor(k); for(i = 0; i < fmin(this->dim, k); i++) { newv->v[i] = this->v[i]; } for(; i < k; i++) { newv->v[i] = 0; } return *newv; } }; // scalar * vektor // Kann keine Methode von vektor sein, weil der erste // Operand kein vektor ist. vektor operator*(const double scalar, const vektor& v) { // vektor v2 = v; return (v * scalar); } // output mittels iostream // Kann keine Methode von vektor sein, weil der erste // Operand kein vektor ist. ostream& operator<<(ostream& left, vektor& right) { for(unsigned int i=0; i < right.dim; i++) { left << right.v[i] << " "; } return left; } class matrix { public: unsigned int dim[2]; // [zeilen,spalten] double **m; matrix(); matrix(unsigned int zeilen, unsigned int spalten) { dim[0] = zeilen; dim[1] = spalten; m = new double*[zeilen]; for(unsigned int i = 0; i < zeilen; i++) { m[i] = new double[spalten]; } }; matrix transp(){ matrix *newm = new matrix (dim[1], dim [0]); for (unsigned int i=0; i<dim[1]; i++){ for (unsigned int j=0; j<dim[0];j++) { newm->m[i][j]= m[j][i]; } } return *newm; } double det(); double spur() { assert(dim[0] == dim[1]); double sum = 0.0; for (unsigned int i = 0; i < dim[0]; i++) { sum = sum + this->m[i][i]; } return sum; } // Matrix + Matrix matrix operator+(const matrix& r) { assert(r.dim[0] == dim[0] && r.dim[1] == dim[1]); matrix *newm = new matrix(dim[0], dim[1]); for (unsigned int i = 0; i < dim[0]; i++) { for (unsigned int j = 0; j < dim[1]; j++) { newm->m[i][j] = m[i][j] + r.m[i][j]; } } return *newm; } matrix operator-(const matrix& r){ assert(r.dim[0] == dim[0] && r.dim[1] == dim[1]); matrix *newm = new matrix(dim[0], dim[1]); for (unsigned int i = 0; i < dim[0]; i++) { for (unsigned int j = 0; j < dim[1]; j++) { newm->m[i][j] = m[i][j] - r.m[i][j]; } } return *newm; } matrix operator*(const matrix&); matrix operator*(const double d) { matrix *newm = new matrix(dim[0], dim[1]); for (unsigned int i = 0; i < dim[0]; i++) { for (unsigned int j = 0; j < dim[1]; j++) { newm->m[i][j] = d * this->m[i][j]; } } return *newm; } vektor operator*(const vektor& v2) { assert (v2.dim==dim[1]); vektor *newv = new vektor(dim[0]); for (unsigned int i=0; i<dim[0]; i++) { newv->v[i] = (this->zeile(i+1)) * v2; } return *newv; } // Liefert eine Zeile als Vektor vektor zeile(unsigned int nr) { assert(nr <= dim[0]); vektor *z = new vektor(dim[1]); for (unsigned int i = 0; i < dim[1]; i++){ z->v[i] = m[nr - 1][i]; } return *z; } vektor spalte(unsigned int nr) { assert(nr<= dim[1]); vektor *r = new vektor (dim[0]); for(unsigned int i=0; i<dim [0]; i++) { r->v[i]=m[i][nr-1]; } return *r; } bool istOrthogonal() { // Ihr Code hier: // 1. Check, dass die matrix quadatisch ist // 2. Rauskriegen, ob die Matrix orthogonal ist // 3. true oder false zurueckgeben } }; int main(int argc, char **argv) { matrix X(2,2); X.m[0][0]= 1; X.m[1][0]= 2; X.m[2][0]= 3; X.m[0][1]= 4; X.m[1][1]= 5; X.m[2][1]= 6; X.m[0][2]= 7; X.m[1][2]= 8; X.m[2][2]= 9; cout << X.istOrthogonal() << endl; cout << X.spur() << endl; }soweit alles klar.
nun war mein erster Gedanke erstmal das ganze zu testen un den matrix operator+ aufzurufencout<<X.operator(X)<<endl;und er bringt mir eine Fehlermeldung. Ist an der Methode
matrix operator+(const matrix& r) { assert(r.dim[0] == dim[0] && r.dim[1] == dim[1]); matrix *newm = new matrix(dim[0], dim[1]); for (unsigned int i = 0; i < dim[0]; i++) { for (unsigned int j = 0; j < dim[1]; j++) { newm->m[i][j] = m[i][j] + r.m[i][j]; } } return *newm; }etwas falsch?
das gleiche bringt er bei transp();
wie man dann die eigentliche Aufgabe löst und auf orthogonalität prüft, glaube ich, weis ich dann.
Vielen Dank für Hilfe
-
viel zu viel
*
viel zu vielnew
viel zu viele Speicherlecks.