Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.
matrix.cpp (Aufgabe 1)
Hi,
müssen bzw. können wir beim Konstruktor Matrix (int, int, T*) überprüfen, ob das Array T die selbe Größe hat, wie das Array _data?
Nein, es ist nicht möglich, du musst einfach davon ausgehen das das Array das du übergeben bekommst die Größe m*n hat.
Ok danke, ja das dachte ich mir schon.
Find ich bissl schwach, da sollte man mindestens ein size_t mitgeben…
Das wuerde auch nicht helfen. Du musst immer noch dem Aufrufer vertrauen, dass der Wert passt. Und m * n ist einfach die noetige Laenge des Arrays - ein weiterer Parameter (ohne Nutzen, denn das ist immer m * n) ist da nur ueberfluessig.
Wenn man schon C++ schreibt könnte man auch einfach einen vector übergeben…
Das wäre aber zu einfach…
Nein, es soll nm sein, es ist nicht immer nm, außer wenn der Aufrufer bei der size ohne nachzudenken n*m eingibt.
Ja, aber es ist nicht möglich es zu überprüfen, daher musst du davon ausgehen das es n*m Elemente Groß sein muss.
Von daher sollte man bei so einer Schnittstelle lieber einen std::vector (oder ein std::array, etc.) verwenden der außer der Größe auch noch mehr Vorteile hat.
So ganz abwegig ist so eine Schnittstelle in der Tat nicht, wenn man bspw. so etwas machen möchte:
float data[] = { 1, 2, 3, 4 };
Matrix mat(2, 2, data);
Hier im Bsp. weiß man natürlich die Größe des Arrays, aber das ist aus der Sicht des Matrix-Konstruktors ja nicht unbedingt bekannt. Daher muss der Benutzer einfach die Schnittstelle korrekt benutzen.
Der std::vector hat übrigens genau so einen Konstruktor, genauso wie (z.B.) die Matrix-Klasse aus OpenCV
Aber sonst hast du natürlich Recht, wenn möglich sollte man std::vector o.ä. verwenden.
Typsicherheit
Bei dem Operator ‘*’ soll eine neue Matrix zurückgegeben werden.
Wenn die beiden Matrizen unterschiedlichen generischen Typen angehören können ganz schön hässliche Dinge passieren.
Sollen/können wir die Typen überprüfen und den genaueren annehmen?
Das sollte eigentlich nicht möglich sein, dass du unterschiedliche Typen hast. Es ist ja beides Templateparamter T.
Ja stimmt ist mir auch grad aufgefallen
Trotzdem würd ich gern wissen ob man die Typen mit irgendeiner Methode erfragen kann.
Ich habs zwar noch nie genutzt, aber vielleicht hilft dir [m]typeid()[/m] weiter: http://www.cplusplus.com/doc/tutorial/typecasting/ (relativ weit unten).
Kann sein, dass das nur T zurückgibt, allerdings steht ja auch was davon da, dass die Information zur Laufzeit gewonnen wird („RTTI“).
Wenn man es auf T anwendet, bekommt man den Anfangsbuchstaben des Typs und in den Objekten scheint das auch irgendwo mit eingebaut zu werden.
Ist zwar nicht schön leserlich, aber genau das was ich wissen wollte, danke.
Sheep hat es schon gesagt, aber nur noch mal zur Klarheit.
[m]T*[/m] ist ein Pointer vom Typ T irgendwie in den Speicher. Wie gross der (gueltige) Block an Daten an dieser Stelle ist, kann die aufgerufene Funktion nicht wissen. Das kann nur ein Byte sein, das kann ein Gibibyte sein ([m]T *x = malloc(1)[/m] vs. [m]T *x = malloc(1<<30)[/m], [m]T *x[/m] ist (bei gleichen Adressen) nicht unterscheidbar). Die Funktion muss dem Aufrufer also vertrauen, dass dieser die richtigen Werte uebergibt (ist allgemein ein Problem in C).
Und da die einzige sinnvolle Moeglichkeit fuer eine n x m Matrix aus n * m Elementen besteht (CRS-Matrix und Co. ausgenommen), reicht das als Parameter. Die Zeilen und Spalten werden ja auch noch einzeln benoetigt.
hey, ich habe eine frage, wenn ich eine matrix erstelle:
Matrix(2,2,{1,2,3,4});
wie hat die dann semantisch auszusehen?
so oder so?
1 2 1 3
3 4 2 4
ich hab das program jetzt erstmal für die erste möglichkeit geschrieben, ich hoffe ich muss das nicht alles umändern.
Schau auf das Aufgabenblatt. Wenn das nicht spezifiziert ist, kannst du es machen wie du willst.
Aber der erste Weg, also Zeilenweise, passt auf jeden Fall.
Für gewöhnlich macht das keinen großen Unterschied, wenn du die getter und setter entsprechend einheitlich hälst. In C++ wählt man öfter die erste Version. Ich glaube in Fortran eher die zweite (ich programmiere kein Fortran, habe da nur so was gehört).
Wenn du Templatetypen erfragen willst kannst du dir Traits anschauen. Das ist aber dann nur für ganz spezielle Szenarien sinnvoll (und ist meines Wissens erst kürzlich in den Standard gewandert, wird also nur in neueren Compilern unterstützt).
auf dem aufgabenblatt habe ich keine spezifikation gefunden,
und einen unterschied stelle ich schon fest:
Matrix(2,2,{1234});
setEntry(0,1,5);
da kämen abhängig von der interpretationsart verschiedene matritzen raus:
1 5 1 5
3 4 2 4
ich denke, ich werd das ganze erstmal so lassen wie es ist.(zeilenweise befüllend)