Operatoren Überladung::Matrizen::Abarbeitung einer mehrfachen Multiplikation
-
Hallo zusammen,
ich möchte eine Klasse Matrix erzeugen, welche in der Lage ist folgende Matrizen-Operation möglichst zügig zu berechnen.
Neue Matrize = Matrix1 * Matrix2 * Matrix3
Meine Unkenntnis ist die, in welcher Richtung wird die Abarbeitung der Multiplikation gemacht ? Wenn ich nun die Überladung (siehe unten) der Matrix2 beispielsweise ausführe, hat sie dann Matrix1 oder Matrix3 während der Ausführungszeit als Input ?
Danke für Eure Zeit und Hilfe
Winn
void operator*(class matrix &matrix)
-
"void operator*(class matrix &matrix)"
bitte etwas weniger schlampig, wenn es um code geht.
binäre operatoren (außer denen mit
assoziieren von links nach rechts,x*y*z ist also dassselbe wie (x*y)*z
-
Hallo,
Machs besser gar nicht so, sondern multipliziere nacheinander. Bei dir wird intern eine temporäre Matrix erzeugt. Desweiteren sollte operator* besser außerhalb der Klasse definiert sein.
-
Gibt es dort denn keine Konvention der man folgen kann ? Der Hintergrund ist der folgende, wenn ich den linken Operanden x in einer Listenform überführe und auf den rechten Operanden y (die Matrix) anwende, hat es sich in meinen Anwendungsfällen als schneller erwiesen. So möchte ich eigentlich mit x*y*z mit entsprechender Überladung erreichen:
- x(Matrix) * y(Matrix) * z(Matrix)
- x(Liste) * y(Matrix) * z(Matrix)
- temp(Matrix) * z(Matrix)
- temp(Liste) * z(Matrix)
- ergebnis(Matrix)
Wenn es keine Konvention gibt, kann ich es eh vergessen.
Desweiteren sollte operator* besser außerhalb der Klasse definiert sein.
Was meinst Du damit genau ?
-
Ich meine damit, dass du den operator* aus der Klasse raus nehmen solltest (halt global).
etwa soTMatrix operator*(const TMatrix& lhs, const TMatrix& rhs);Das in deinem ersten Beitrag ist ja wohl hoffentlich nicht die Deklaration deines Operators.
-
Okay, also eine externe Funktion...
Braunstein schrieb:
Das in deinem ersten Beitrag ist ja wohl hoffentlich nicht die Deklaration deines Operators.
Doch ist es - ich gehe davon aus, daß automatisch Kopien erstellt werden und zwar in der Form:
- ergebnis=NULL-Pointer
1a) x(Matrix) * y(Matrix) * z(Matrix)
1b) x(Matrix) * y'(Kopie von y) * z(Matrix)- x(Liste) * y'(Kopie von y) * z(Matrix)
3a) y'(Matrix) * z(Matrix)
3b) y'(Matrix) * z'(Kopie von z)-
y'(Liste) * z'(Kopie von z)
-
ergebnis=z'(Matrix), y' wird gelöscht
Diese Abarbeitung innerhalb eines Prozessors würde auch bei einer normalen Multiplikation Sinn machen finde ich, oder nicht ?
-
Winn schrieb:
Braunstein schrieb:
Das in deinem ersten Beitrag ist ja wohl hoffentlich nicht die Deklaration deines Operators.
Doch ist es -
und dieser operator liefert also nix zurück?
-
Müßte er auch nicht, weil der Wert in die Klasse geschrieben wird... funktionierte sogar in einem Testbeispiel...
Allerdings verstehe ich nicht, daß die Operatoren-Überladung "nur" zwei Operatoren zu läßt, also x+y. Wenn ich x+y+z mache, bekomme ich einen Compiler Fehler (Gcc 4.01) "main.cpp:46: error: no match for 'operator+' in 'x. count::operator+(((count&)(& y))) + z'". Das Beispiel arbeitet mit Rückgabe, so wie ihr es vorgeschlagen hattet.
Was fehlt in meiner Klassen-Definition bzw. Deklaration ?
#include <stdio.h> #include <stdlib.h> class count { private: double dValue; public: bool showCount() { fprintf(stderr,"Zahl:: %lg\n",dValue); return true; } bool setCount(double val) { dValue=val; return true; } double getValue() { return dValue; } count() { dValue=0.; } count(double val) { this->setCount(val); } count(class count *zahl) { dValue=zahl->getValue(); this->showCount(); } count(class count &zahl) { dValue=zahl.getValue(); this->showCount(); } void operator=(class count &zahl) { dValue=zahl.getValue(); this->showCount(); } class count *operator*(class count &zahl) { class count *foo = new count[1]; foo->setCount(dValue*zahl.getValue()); foo->showCount(); return foo; } class count *operator+(class count &zahl) { class count *foo = new count[1]; foo->setCount(dValue+zahl.getValue()); foo->showCount(); return foo; } class count *operator-(class count &zahl) { class count *foo = new count[1]; foo->setCount(dValue-zahl.getValue()); foo->showCount(); return foo; } class count *operator*(class count *zahl) { class count *foo = new count[1]; foo->setCount(dValue*zahl->getValue()); foo->showCount(); return foo; } class count *operator+(class count *zahl) { class count *foo = new count[1]; foo->setCount(dValue+zahl->getValue()); foo->showCount(); return foo; } class count *operator-(class count *zahl) { class count *foo = new count[1]; foo->setCount(dValue-zahl->getValue()); foo->showCount(); return foo; } ~count() { dValue=0.; } }; int main () { class count x(1); class count y(3); class count z(5); class count *ergebnis = NULL; x.showCount(); y.showCount(); z.showCount(); ergebnis=x+y; ergebnis->showCount(); delete[] ergebnis; ergebnis=NULL; ergebnis=x+y+z; // <<== Funktioniert nicht, Compiler Fehler s.o. ergebnis->showCount(); delete[] ergebnis; ergebnis=NULL; return 0; }
-
Die Operatoren sollten keine Zeiger zurückgeben, sondern Objekte:
count operator*(const count& zahl) { count tmp; tmp.value=value*zahl.value; return tmp; }So klappt es auch mit der Verkettung der Operatoren.
-
CStoll schrieb:
Die Operatoren sollten keine Zeiger zurückgeben, sondern Objekte:So klappt es auch mit der Verkettung der Operatoren.
Das stimmt... aber die Werte-Übergabe bekomme ich irgendwie nicht hin.
int main () { class count x(1); class count y(3); class count z(5); class count *ergebnis = NULL; x.showCount(); y.showCount(); z.showCount(); fprintf(stderr,"\n"); x+y+z; (x+y+z)*z-y; ergebnis=&(x+y); ergebnis->showCount("hat's den wert noch ?"); return 0; }Meine Ausgabe:
Zahl ((null)):: 1
Zahl ((null)):: 3
Zahl ((null)):: 5Zahl (+Operator):: 4
Zahl (+Operator):: 9
Zahl (+Operator):: 4
Zahl (+Operator):: 9
Zahl (*Operator):: 45
Zahl (-Operator):: 42
Zahl (+Operator):: 4
Zahl (hat's den wert noch ?):: 0#include <stdio.h> #include <stdlib.h> class count { private: double dValue; public: bool showCount(char *comment=NULL) { fprintf(stderr,"Zahl (%s):: %lg\n",comment,dValue); return true; } bool setCount(double val) { dValue=val; return true; } double getValue() { return dValue; } count() { dValue=0.; } count(double val) { this->setCount(val); } count(class count &zahl) { dValue=zahl.getValue(); this->showCount("Konstruktor"); } void operator=(class count &zahl) { dValue=zahl.getValue(); this->showCount("v=Konstruktor"); } class count operator+(class count &zahl) { class count foo(0.); foo.setCount(dValue+zahl.getValue()); foo.showCount("+Operator"); return foo; } class count operator-(class count &zahl) { class count foo(0.); foo.setCount(dValue-zahl.getValue()); foo.showCount("-Operator"); return foo; } class count operator*(class count &zahl) { class count foo(0.); foo.setCount(dValue*zahl.getValue()); foo.showCount("*Operator"); return foo; } ~count() { dValue=0.; } };
-
Was soll denn das Gegurke (sorry) mit den Zeigern? Du kannst die Objekte ganz normal per Wert übernehmen und weiterreichen:int main () { count x(1); count y(3); count z(5); count ergebnis; ergebnis=(x+y)*z; ergebnis.showCount("hat's den wert noch ?"); return 0; }
-
main.cpp:58: error: no match for 'operator=' in 'ergebnis = count::operator-(count&)(((count&)(& y)))'
Weil mein Compiler die Arbeit verweigert
Die Fehlermeldung ist eigentlich auch ganz logisch, denn die Operatoren Überladung erzeugt ein Objekt dessen Inhalt ich in ein schon vorhandenes Objekt legen möchte...
-
Was für eine Zeile erzeugt denn diesen Fehler? Das sieht zumindest ganz danach aus, daß du deinen operator= vermurkst hast (für Operator-Verkettung sollte der übrigens *this per Referenz zurückgeben).
PS: Noch ein Schönheitsfehler: In C muß man 'struct irgendwas' immer mit angeben, in C++ kannst du das 'class' weglassen, wenn du den Typ verwenden willst.
-
CStoll schrieb:
Das sieht zumindest ganz danach aus, daß du deinen operator= vermurkst hast
In der Tat, es fehlte mir der Adress-Operator "&"
Vielen Dank 
#include <stdio.h> #include <stdlib.h> class count { private: double dValue; public: bool showCount(char *comment=NULL) { fprintf(stderr,"Zahl (%s):: %lg\n",comment,dValue); return true; } bool setCount(double val) { dValue=val; return true; } double getValue() { return dValue; } count() { dValue=0.; this->showCount("Create"); } count(double val) { this->setCount(val); this->showCount("Init"); } count(class count &zahl) { dValue=zahl.getValue(); this->showCount("Copy"); } class count &operator=(class count &zahl) { if (this==&zahl) return *this; this->setCount(zahl.getValue()); this->showCount("Assign"); return *this; } class count &operator+(class count &zahl) { fprintf(stderr,"+Operator::%lg + %lg =",this->getValue(),zahl.getValue()); this->setCount(dValue+zahl.getValue()); fprintf(stderr," %lg\n",this->getValue()); return *this; } class count &operator-(class count &zahl) { fprintf(stderr,"-Operator::%lg - %lg =",this->getValue(),zahl.getValue()); this->setCount(dValue-zahl.getValue()); fprintf(stderr," %lg\n",this->getValue()); return *this; } class count &operator*(class count &zahl) { fprintf(stderr,"*Operator::%lg * %lg =",this->getValue(),zahl.getValue()); this->setCount(dValue*zahl.getValue()); fprintf(stderr," %lg\n",this->getValue()); return *this; } ~count() { dValue=0.; } }; int main () { class count x(1); class count y(3); class count z(5); class count ergebnis; ergebnis=(x+y+z)*z-y; ergebnis.showCount("hat's den wert noch ?"); return 0; }