PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : überladen von operatoren



pucki
14-11-2005, 14:05
hi,

ich habe ein kleines problem mit meinen einer von meinen klassen.


class Vector {
friend class matrix;
private:
int len;
double* daten;

public:
Vector(int n=1);
Vector(Vector *vek);
Vector(const Vector &vek);
~Vector();

double& operator[](int n);
friend istream& operator>>(istream&, Vector&);
friend ostream& operator<<(ostream&, const Vector&);

int const size();

};


und


class Matrix {
private:
int len, num;
static int anz;
Vector **daten;

public:
Matrix(int n);
Matrix(Matrix&);
~Matrix();

Vector* operator[](int n);
Matrix& operator+=(Matrix&);
Matrix& operator-=(Matrix&);


friend Matrix operator+(const Matrix& mat_1, const Matrix& mat_2);
friend Matrix operator-(const Matrix& mat_1, const Matrix& mat_2);


friend istream& operator>>(istream&, Matrix&);
friend ostream& operator<<(ostream&, Matrix&);

int const size();
};


im grossen und ganzen funktioniert eigentlich fast alles ;-).

Nur das Überladen der Operatoren "+" und "-" der Klasse Matrix macht Probleme. wenn ich das ändere und einen Pointer zurückgebe, dann wird das temperäre Objekt nicht gelöscht. die berechnung jedoch funktioniert.

im internet habe ich ein Beispiel mit der Klasse Bruch gefunden. Die Rückgabe funktioniert da wunderbar, da werden allerdings keine Pointer in der Klasse verwendet. Das Attribut daten vom Typ Vector ** ist jedoch in der Programmieraufgabe vorgegeben.

hätte da noch jemand einen tip?

locus vivendi
14-11-2005, 14:13
hätte da noch jemand einen tip?
Was ist denn nun eigentlich das Problem?

pucki
15-11-2005, 21:50
hi,

sorry, war wohl ein wenig knapp gehalten die info ...

also anbei hängen noch die files zu dem ganzen, allerdings wurde der operator anders als oben aufgeführt implementiert.

dem ganzen sind debug ausgaben hinzugefügt.

- adresse der matrix die erstellt wird
- adressen der vektoren

dabei ist mir aufgefallen, dass hier die adressen der temporär erstellten vektoren in die matrix kopiert werden und nicht der inhalt.
....

bei den beispielen die ich im internet gefunden habe, wird keine referenz zurückgegeben, sondern ein objekt. das dann in das ziel kopiert wird. dort wird jedoch im der methode kein pointer verwendet sondern ein objekt erstellt.
z.B.:


mcomplex operator+(const mcomplex &c1,const mcomplex &c2)
{
mcomplex erg=c1;
erg+=c2;
return erg;
}

das funktioniert auch wunderbar, nur wenn ich meinen code dieser vorlage versuche anzupassen muckt der compiler. zuerst dachte ich dass der copy construktor dafür verantwortlich ist, dass die zuweisung nicht funktioniert, aber der wird gar nicht aufgerufen.
na ja, irgendwie möchte ich das schon hinbekommen .. vielleicht hätte ja jemand einen tip ....

eingefügt:

nun das mit dem copy- construktor habe ich zwischenzeitlich ein wenig überarbeitet, ich hatte das const vergessen.
desweiteren hat der im anhang enthaltene construktor noch einen fehler im copieren der vektoren. er kopiert nur die adressen nicht die vektoren selbst. dabei kommt heraus, dass nun eine komplette matrix incl. vektoren in der luft hängt .... (imho). dies schliesse ich einfach daraus, dass für dieses objekt kein destruktor aufgerufen wird.

gruesse reinhard

files wurden entfernt ...

locus vivendi
16-11-2005, 21:58
bei den beispielen die ich im internet gefunden habe, wird keine referenz zurückgegeben, [...]
Lass es sein, wär mein Tipp. Gib aus den binären Operatoren keine Referenzen zurück. Bezüglich des Überladens von Operatoren gibt es eine einfache Regel: Im Zweifel gilt "Do as the ints do." (ist glaube ich von Scott Meyers). Und die Ints geben für soetwas wie a + b auch keine Referenzen zurück.

Dein Code hat übrigens noch mehr Probleme mit dem Speicher-Management bzw. Ausnahmefestigkeit. Du kannst ja mal hier reinlesen:
http://www.research.att.com/~bs/3rd_safe0.html

pucki
17-11-2005, 09:10
Lass es sein, wär mein Tipp. Gib aus den binären Operatoren keine Referenzen zurück. Bezüglich des Überladens von Operatoren gibt es eine einfache Regel: Im Zweifel gilt "Do as the ints do." (ist glaube ich von Scott Meyers). Und die Ints geben für soetwas wie a + b auch keine Referenzen zurück.

Dein Code hat übrigens noch mehr Probleme mit dem Speicher-Management bzw. Ausnahmefestigkeit. Du kannst ja mal hier reinlesen:
http://www.research.att.com/~bs/3rd_safe0.html

jup,
also das exception-handling kommt erst noch in der vorlesung dran, darum habe ich auch nur mit "assert" gearbeitet, also aussteigen und sagen wo ....

da ich einen fehler im copy-constructor hatte, hat der compiler bislang auch die rückgabe eines objektes verweigert ...
dass bei der rückgabe einer referenz nur ärger habe, das vermutete ich bereits. bei der überprüfung welche objekte durch den destruktor zerstört wurden, ist mir ja aufgefallen, dass ein objekt noch in der "luft" hängt. und zwar das temporär erstellte objekt.

ich werde dann wohl mit der klasse matrix nochmals neu beginnen.
- richtig deklarierter copy- constructor
- +operator mit rückgabe eines objektes
und werde mal prüfen ob ich den zuweisungsoperator auch noch überladen muss. alles andere fliegt erst mal raus. (+=, -=, -, ) außer (<<, >>, []) die brauch ich ....

wenn du sonst noch einen tip hättest, was außer dem exception-handling noch schief geht, wäre ich dir dankbar. ich muss zur zeit leider aufpassen dass ich nicht zu viel zeit reinstecke und trotzdem keine fehler reinbaue ...
unserem dozenten prüft derweil mal ob meine aussage bezüglich der zerstörung der objekte korrekt ist ;-) (der ist schon ganz genervt ... ;-) )

gruesse reinhard

pucki
17-11-2005, 19:25
hi,
so sieht es schon wesentlich besser aus. nun werden alle erstellten objekte auch wieder gelöscht.


----------------------------------------------
neue Matrix: n1 - 0xbfa91ce4
vec n: 1 0x804c018 0x804c028 0x804c030
vec n: 2 0x804c040 0x804c050 0x804c058
neue Matrix: n2 - 0xbfa91cd8
vec n: 3 0x804c078 0x804c088 0x804c090
vec n: 4 0x804c0a0 0x804c0b0 0x804c0b8
Eingabe einer Matrix:
1 von 2 : Eingabe eines Vektors:
1 von 2 : 1
2 von 2 : 2
2 von 2 : Eingabe eines Vektors:
1 von 2 : 3
2 von 2 : 4
jetzt geht es gleich los ;-)
- der operator -
neue Matrix: n3 - 0xbfa91ccc
vec n: 5 0x804d290 0x804d2a0 0x804d2a8
vec n: 6 0x804d2b8 0x804d2c8 0x804d2d0
Zuweisung: - es wird zugewiesen
-
- der operator +
neue Matrix: n4 - 0xbfa91cc0
vec n: 7 0x804d2f0 0x804d300 0x804d308
vec n: 8 0x804d318 0x804d328 0x804d330
-
neue Matrix: n5 - 0xbfa91cb4
vec n: 9 0x804d350 0x804d360 0x804d368
vec n: 10 0x804d378 0x804d388 0x804d390
-
- der operator +
neue Matrix: n6 - 0xbfa91cf0
vec n: 11 0x804d3b0 0x804d3c0 0x804d3c8
vec n: 12 0x804d3d8 0x804d3e8 0x804d3f0
- es wird zugewiesen
vec d: 11 0x804d3b0 0x804d3c0 0x804d3c8
vec d: 12 0x804d3d8 0x804d3e8 0x804d3f0
del m: 6 - 0xbfa91cf0
-
Es wird eine Matrix ausgegeben: 1
( 1, 2 )
( 3, 4 )

Es wird eine Matrix ausgegeben: 2
( 1, 2 )
( 3, 4 )

Es wird eine Matrix ausgegeben: 3
( -1, -2 )
( -3, -4 )

Es wird eine Matrix ausgegeben: 4
( 2, 4 )
( 6, 8 )

Es wird eine Matrix ausgegeben: 5
( 1, 2 )
( 3, 4 )

jetzt wird geloescht!!
vec d: 9 0x804d350 0x804d360 0x804d368
vec d: 10 0x804d378 0x804d388 0x804d390
del m: 5 - 0xbfa91cb4
vec d: 7 0x804d2f0 0x804d300 0x804d308
vec d: 8 0x804d318 0x804d328 0x804d330
del m: 4 - 0xbfa91cc0
vec d: 5 0x804d290 0x804d2a0 0x804d2a8
vec d: 6 0x804d2b8 0x804d2c8 0x804d2d0
del m: 3 - 0xbfa91ccc
vec d: 3 0x804c078 0x804c088 0x804c090
vec d: 4 0x804c0a0 0x804c0b0 0x804c0b8
del m: 2 - 0xbfa91cd8
vec d: 1 0x804c018 0x804c028 0x804c030
vec d: 2 0x804c040 0x804c050 0x804c058
del m: 1 - 0xbfa91ce4

----------------------------------------------
Program exited successfully with errcode (0)
Press the Enter key to close this terminal ...


anbei hängen noch die files (*.cc und *.h). wenn jemand noch zeit und musse findet noch einen blick drauf zu werfen, bin ich über jeden tip dankbar. das exception - handling wie von locus vivendi angesprochen wird erst in 14 tagen behandelt und mir fehlt einfach die zeit das vorzuarbeiten.

gruesse reinhard