Eigenen Datentyp?
-
Hacker schrieb:
Stop. Wieso? Der C++11-Standard behält doch viel vom alten.
Mit dem Textverständnis ists heute nicht so weit her, oder? Der neue Standard enthält Dinge, die nicht im alten Standard stehen (sonst bräuchte man gar keinen neuen Standard). Also "gibt es noch mehr Dinge im C++11 Standard, die der 98er Standard noch nicht kennt". Das hat nix damit zu tun, dass der neue Standard gut über den alten Standard Bescheid weiß.
-
Hacker schrieb:
Quatsch, es erleichtert allen Pro's das Lesen.
Woher weißt du das, kennst du einen?
-
Bashar schrieb:
Hacker schrieb:
Quatsch, es erleichtert allen Pro's das Lesen.
Woher weißt du das, kennst du einen?
Er müsste sogar ziemlich viele kennen, um eine Aussage über alle "Pro's" (das tut so weh beim Lesen, haben wir auch Leute hier, die "Tisch'e" schreiben?) machen zu können.
-
Na,
#include <iostream> int main() { std::cout << "A" << std::endl; }
ist IMO viel schöner als
#include <iostream> int main() { std::cout << "A" << std::endl; return 0; }
-
Hacker schrieb:
Na, [2-SLOC-Code] ist IMO viel schöner als [3-SLOC-Code]
Bläht das ganze Programm ja auch um die Hälfte auf.
Ich als Pro würde natürlich schreiben
int main() { return !(std::cout << "A\n"); }
-
Kann da überhaupt was schiefgehen?
-
Hacker schrieb:
...
-
Hacker schrieb:
1. Kein
return 0;
2. Keinsystem("pause");
3. Du hast den Destruktor nicht definiert -> lösch die "~meinDatentyp();
" Zeile wenn er sowieso trivial sein soll
4. Den Konstruktor hast du ebenso wenig definiert -> änder in Zeile 24void meinDatentyp::init(int n)
zu
void meinDatentyp::meinDatentyp(int n)
Soviel erstmal.
Bitte Initialisierungs-listen verwenden:void meinDatentyp::meinDatentyp(int n): feld( new int[n]() ) { }
Mit dem
()
nach den Indiz-Klammern wird automatisch alles mit 0 initialisiert.void meinDatentyp::min() { int ergebnis = 0; float mittelwert = 0;//wird nicht verwendet (sollte warnungen geben) for(int i(0); i < n; i++) ergebnis = ergebnis + feld[i]; std::cout << "Mittelwert = " << static_cast<float>(ergebnis) / n; // C++-Casts }
NIE
using namespace ...;
in Headern!srand(...)
muss in diemain()
(wird nur einmal ausgeführt)Danke, hab das jetzt mal alles umgesetzt und es scheint zu funktionieren! Danke!
Ich hätt hier übrigens wieder ein neues "Problem". Die methode "add" soll mir das Ergebnis der Matrizenaddition zurückgeben. Wenn ich allerdings "return ergebnis;" am Ende der methode schreibe, mosert der Compiler, dass "ergebnis" deklariert sei! Was hat das zu bedeuten? Hier der Code:
#include<iostream> using namespace std; class matrix { private: int m; int n; int size; int *feld; public: matrix(int m, int n); ~matrix(); void init(); void print(); void input(); matrix *add(matrix *M); void mult(); }; matrix::matrix(int m, int n) { this->m = m; this->n = n; size = m*n; feld = new int [size]; } //Konstruktor matrix::~matrix() { delete feld; } //Destruktor void matrix::init() { for(int i=0; i<size; i++) { feld[i] = 0; } } void matrix::print() { int counter = 0; for(int i=0; i<m; i++) { for(int j=0; j<n; j++) { cout << feld[counter++]; } cout << endl; } } void matrix::input() { for(int i=0; i<size; i++) { cout << "Wert " << i << " eingeben: "; cin >> feld[i]; } } matrix *matrix::add(matrix *M) { if((M->m != m) || (M->n != n)) { cout << "Matrizen nicht gleich gross! Abbruch!"; } else { matrix *ergebnis = new matrix (m,n); for(int i=0; i<size; i++) { ergebnis->feld[i] = feld[i] + M->feld[i]; } } return ergebnis; } int main() { matrix myMatrix(2,2), myMatrix_M(2,2); myMatrix.init(); myMatrix.input(); myMatrix.print(); myMatrix_M.init(); myMatrix_M.input(); myMatrix_M.print(); myMatrix.add(&myMatrix_M); }
PS: Das "using namespace std;" hab ich jetzt dennoch mal drin gelassen, da es mir jetzt zu aufwändig war, überall den Scope-Operator zu setzen! Sorry, aber das is mir echt zu viel Aufwand, auch wenn es "poor-style" is!
-
vip@r schrieb:
Ich hätt hier übrigens wieder ein neues "Problem". Die methode "add" soll mir das Ergebnis der Matrizenaddition zurückgeben. Wenn ich allerdings "return ergebnis;" am Ende der methode schreibe, mosert der Compiler, dass "ergebnis"
nicht deklariert sei! Dann pack
return ergebnis
vor die vorletzte}
.Und eine weitere gute Frage wäre: Who deletes that object?
-
matrix *matrix::add(matrix *M) { if((M->m != m) || (M->n != n)) { cout << "Matrizen nicht gleich gross! Abbruch!"; } else { matrix *ergebnis = new matrix (m,n); for(int i=0; i<size; i++) { ergebnis->feld[i] = feld[i] + M->feld[i]; } } return ergebnis; }
Er meckert, dass es nicht deklariert ist. Ist es auch nicht. Wie dir (schon lange hoffe ich) klar sein dürfte, bilden Bereiche in den geschweiften Klammern eigene
Namensräume(danke an gugelmoser) scopes aus. Es müsste wahrscheinlich so aussehen:matrix *matrix::add(matrix *M) { if(M->m != m || M->n != n) { std::cout << "Matrizen nicht gleich gross! Abbruch!";//Hier kannst du ja auch was werfen return 0; } matrix *ergebnis = new matrix (m,n); else for(int i=0; i < size; i++) ergebnis->feld[i] = feld[i] + M->feld[i]; return ergebnis; }
-
Hacker schrieb:
bilden Bereiche in den geschweiften Klammern eigene Namensräume aus.
Namensraum ist hierfür das falsche Wort.
-
Gugelmoser schrieb:
Hacker schrieb:
bilden Bereiche in den geschweiften Klammern eigene Namensräume aus.
Namensraum ist hierfür das falsche Wort.
Korrigiert.
-
Hacker schrieb:
Gugelmoser schrieb:
Hacker schrieb:
bilden Bereiche in den geschweiften Klammern eigene Namensräume aus.
Namensraum ist hierfür das falsche Wort.
Korrigiert.
:p Das nennt sich
compound statement
(Verbundanweisung / Block). Und eine Verbundanweisung führt einenlocal scope / block scope
ein.
-
What the? Matrixaddition gibt Speicher zurück den man wieder freigeben muss? Ist das ernst gemeint?
-
cooky451 schrieb:
Ist das ernst gemeint?
Vermutlich nicht so ganz, sondern einfach nur von einer der zig bestehenden Uralt-Bibliotheken inspiriert, die genau solche Dummheiten machen. Sowas von 90er
-
Danke für eure Antworten! Dass diese Variable im compound statment der else-Abzweigung gültig ist, ist mir natürlich schon länber bewusst. Ich hab halt nur noch nicht so die große Erfahrung, dass ich solche Fehler auf Anhieb sehe. Danke an euch!
Gugelmoser schrieb:
Und eine weitere gute Frage wäre: Who deletes that object?
Dass hier noch nicht zerstört wird, ist auch klar. Das sollte ich wohl auch noch implementieren. Danke! Ich liefere bei Gelegenheit den gesamten Code nach. Wahrscheinlich heute noch.
pumuckl schrieb:
cooky451 schrieb:
Ist das ernst gemeint?
Vermutlich nicht so ganz, sondern einfach nur von einer der zig bestehenden Uralt-Bibliotheken inspiriert, die genau solche Dummheiten machen. Sowas von 90er
Bitte zerreisst halt meinen Code jetzt nicht in so große fetzen. Es funktioniert. Ich bin halt noch etwas unerfahren. Übung macht den Meister und nur durch die Fehler bei der Übung lernt man. Wie hättet ihr denn das gemacht? Mir war halt einfach nur diese Möglichkeit in den Sinn gekommen, dass die Additionsfunktion einen Speicherbereich auf das Ergebnis zurückgibt!
-
vip@r schrieb:
Bitte zerreisst halt meinen Code jetzt nicht in so große fetzen. Es funktioniert.
Das ist kein gutes Kriterium. Eine Bruchbude, die beim ersten Windstoß einfällt, nennst du auch nicht Haus, bloß weil es momentan noch hält.
Ich bin halt noch etwas unerfahren. Übung macht den Meister und nur durch die Fehler bei der Übung lernt man. Wie hättet ihr denn das gemacht?
Guck doch auf der ersten Seite! Da habe ich einen langen Roman mit vielen googlebaren Stichwörtern geschrieben, wie man den Code ganz einfach (sogar einfacher als er momentan ist!) viel robuster machen kann, so dass man sich um gar nichts mehr sorgen braucht und es einfach funktioniert. Außerdem habe ich dir erklärt, was am Momentanen Code nicht so gut ist.
Dein Beitrag auf Seite 3 hat mich dann doch etwas entsetzt
, denn wie es scheint, hast du dir nicht einmal die Mühe gemacht, meine Erklärungen auch nur quer zu lesen, geschweige denn, dich mal mit den Stichworten weiterzubilden.
-
SeppJ schrieb:
Dein Beitrag auf Seite 3 hat mich dann doch etwas entsetzt
, denn wie es scheint, hast du dir nicht einmal die Mühe gemacht, meine Erklärungen auch nur quer zu lesen, geschweige denn, dich mal mit den Stichworten weiterzubilden.
Bevor du hier mich mit irgendwelche bösen Smileys in die Schranken versuchst zu weisen, solltest du vielleicht vorher überhaupt erstmal wissen, dass ich laut meiner Aufgabe eine Methode init() schreiben soll, die das mit "new int [size]" allokierte Array mit 0en initialisiert! Wenn ich nun mit "new int [size] ()" im Konstruktor das allokierte Array schon mit 0en belege, wird die Methode "init()" überflüssig. Ich MUSS aber eine Methode init() schreiben" Somit kann ich auf deinen Verbesserungsvorschlag nicht eingehen, weil ich sonst mein Übungsziel nicht erreiche, welches ja ist, eine Methode "init() zu schreiben"!
SeppJ schrieb:
Ich nehme mal an, du machst das nur zur Übung und nicht, weil du std::vector nicht kennst:
Doch, "vector" kenn ich. Darf/soll ich nur nicht benutzen!
Nichtsdestotrotz halte ich mal noch weiterhin an meinem "schlechtn Code" fest. Denn ehrlich gesagt hilft mir nur mein Code weiter;
. . . matrix *matrix::add(matrix *M) { if((M->m != m) || (M->n != n)) { cout << "Matrizen nicht gleich gross! Abbruch!"; } else { matrix *ergebnis = new matrix (m,n); for(int i=0; i<size; i++) { ergebnis->feld[i] = feld[i] + M->feld[i]; } return ergebnis; } } int main() { matrix myMatrix(2,2), myMatrix_M(2,2); myMatrix.init(); myMatrix.input(); myMatrix.print(); myMatrix_M.init(); myMatrix_M.input(); myMatrix_M.print(); myMatrix.add(&myMatrix_M); system("pause"); return 0; }
Das return ergebnis liefert nun einen Speicherbereich zurück. Wie kann ich mir nun in der main-Fkt. mir das Ergebnis lassen? Das versteh ich grad nicht. Wenn ich bspw. "cout << myMatrix.add(&myMatrix_M);" schreibe, dann wird nur die Adresse ausgegeben an der das Ergebnis steht, nicht aber die berechneten Werte selbst...
-
vip@r schrieb:
Bevor du hier mich mit irgendwelche bösen Smileys in die Schranken versuchst zu weisen, solltest du vielleicht vorher überhaupt erstmal wissen, dass ich laut meiner Aufgabe eine Methode init() schreiben soll, die das mit "new int [size]" allokierte Array mit 0en initialisiert!
Dann reich das an deinen Lehrer weiter. Ich hoffe, du wirst hoffentlich aus dem Kurs nur eine gute Note mitnehmen und den Inhalt anschließend vergessen.
Das return ergebnis liefert nun einen Speicherbereich zurück. Wie kann ich mir nun in der main-Fkt. mir das Ergebnis lassen? Das versteh ich grad nicht. Wenn ich bspw. "cout << myMatrix.add(&myMatrix_M);" schreibe, dann wird nur die Adresse ausgegeben an der das Ergebnis steht, nicht aber die berechneten Werte selbst...
Da ich gerade 5 Seiten Thread nicht vollstandig lesen mag: Ist der Wahnsinn, ein mit new angefordertes Objekt per Pointer aus der Additionsmethode herauszugeben (anstatt wie üblich ein "richtiges" Objekt) auch eine Vorgabe oder deine eigene Idee? Falls letzteres: Eine Addition im Sinne von a + b sollte ein neues (const) Objekt als Rückgabewert haben (dieser Fall liegt hier vor), eine Addition im Sinne von a += b sollte eine Referenz auf *this als Rückgabewert haben (nur zur Info). Dies anders zu machen führt erfahrungsgemäß nur zu Scherereien, insbesondere das Übertragen von Objektverantwortung (wie hier durch das herausgeben eines noch freizugebenden Speicherbereichs) ist eine Todsünde.
Wenn ich bspw. "cout << myMatrix.add(&myMatrix_M);" schreibe, dann wird nur die Adresse ausgegeben an der das Ergebnis steht, nicht aber die berechneten Werte selbst...
myMatrix.add(&myMatrix_M) ist ja auch ein Zeiger auf das Ergebnis, nicht das Ergebnis selber. Du müsstest den Zeiger schon noch dereferenzieren, um an das Ergebnis zu kommen. Aber wie oben erklärt, ist das sowieso eine ungünstige* Methode, das überhaupt mit Pointern zu machen.
*: Um deine empfindlichen Gefühle zu schonen nenne ich das nur "ungünstig" anstatt "totalen Bockmist", der es eigentlich ist. Wirst du die Stelle nun trotzdem ändern oder wiegst du dich durch die Vermeidung von Klartext meinerseits nun in Sicherheit, da "ungünstig" ja nicht so schlimm ist?
-
SeppJ, SeppJ! Guck mal, was ich gebastelt hab! Ich mache es später noch mit einem Allokator.