Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Überladener Operator verändert Variable wo ers nicht soll

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
05.08.2008, 14:23 Uhr
murenius



Hallo,

ich habe eine eigene Klasse zur Repräsentation von Punktenim Raum geschrieben, nämlich "template <int d> class Point"

Um zwei Instanzen dieser Klasse einfach addieren zu können hab ich folgenderweise das + überladen:


C++:
  Point& operator + (const Point& p)
  {
    if (this != &p)
      for (int i=0; i<d; ++i)
        coord[i] += p.coord[i];
    return *this;
  }



Später habe ich dann einen vector mit solchen Punkten und übergebe ihn einer Funktion:


C++:
void covarianceMatrix(Matrix &cov, vector<Point<3>> pointvec, int numPts){



Innerhalb dieser Funktion nutze ich dann den überladenen Operator (c ist ein weiterer Point<3>):


C++:
Point<3> p = (pointvec[i] - c);



Und jetzt kommt das Problem... die Werte in pointvec werden durch die Nutzung des Operators verändert, was sie definitiv nicht sollten. Offenbar habe ich irgendetwas Grundsätzliches nicht verstanden, ich hab einige Tutorials gewälzt (daher hatte ich auch den grundlegenden Code für das Überladen) aber nicht gefunden, was genau das Problem ist.

Könnte mir jemand bitte helfen, allein weiß ich erstmal nicht weiter?

Herzlichen Dank und viele Grüße
Murenius

Dieser Post wurde am 05.08.2008 um 14:23 Uhr von murenius editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
05.08.2008, 16:16 Uhr
xXx
Devil


Ja du hast operator + wie operator += implementiert
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
05.08.2008, 16:20 Uhr
xXx
Devil



C++:
const Point Point::operator+(Point const & rhs) const
{
    return Point(*this) += rhs;
}

Point& Point::operator+=(Point const & rhs)
{
    for (std::size_t (0); i < d; ++i) coord[i] += rhs.coord[i];
    return *this;
}
so und du bist fertig :P
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
05.08.2008, 16:21 Uhr
stephanw
localhorst


3 Dinge:

1.) Hast Du auch eine Klasse Vector für Vektoren im Raum ? Dann wäre es sinnvoll, die Addition von Punkt und Punkt nicht zu ermöglichen, weil dies mathematisch nicht richtig ist. Man kann einen Vektor zu einem Punkt addieren und erhält wieder einen Punkt. Aber zwei Punkte kann man nicht addieren.

2.) Dein Code verwendet einen "-"-Operator, obwohl Du von "+" schreibst. Ich gehe mal davon aus, dass Du Dich beim "-" verschrieben hast oder Du den "-"-Operator in gleicher Weise implementiert hast.

3.) Zum eigentlichen Problem:

Deine Implementierung von Point::operator+() verändert doch die Member-Variablen der Instanz, für die er aufgerufen wird (linksseitiger Operand). Von daher ist es klar, dass der Punkt in pointvec[i] verändert werden. Was Du aber offenbar möchtest ist, einen neuen Punkt als Summer der beiden Operanden anzulegen.

Du kannst jetzt zwei Dinge tun:
a.) Entweder implementierst Du Deinen Operator auf diese Weise:

C++:
class Point
{
  ..
  Point operator+(const Point& p)
  {
    Point result;
    result.x = x + p.x;
    ...
    return result;
  }



oder

b.) Du verwendest für den Operator keine Member-Funktion, sondern eine globale Funktion (oder in einem Namespace, jedenfalls keine Member-Funktion):


C++:

Point operator+(const Point& a, const Point& b)
{
  Point result;
  ...
  return result;
}



Diese Option b.) ist besser, weil sie der gewünschten Semantik am besten entspricht.

Es gibt eine gute Konvention: Operatoren, die keine Member-Variablen ändern (so wie "+","-", usw.) sind auch keine Member-Funktionen. Sie müssen also global oder in einem passenden Namespace definiert werden.
Operatoren, die das Objekt ändern sollen, sind auch Member-Funktionen. Beispiele dafür ist z.B. "+=", "-=" usw.
--
Reden ist Schweigen und Silber ist Gold.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
05.08.2008, 17:11 Uhr
murenius



Herzlichen Dank schonmal für die Hinweise, das war mein erster Versuch mit überladenen Operatoren.

Oh ja, das mit dem - ist natürlich ein Fehler meinerseits gewesen, da fehlte ein Zwischenschritt, aber ich habe beides implementiert und das natürlich analog.

Die Punkte sind schon ok, das Addieren brauche ich um das Massezentrum einer Punktwolke zu bekommen. Ansonsten hab ich eine Vektorklasse oder ich benutz einfach einen Point<4> und arbeite mit homogenen Koordinaten.

Keine Ahnung wie ich das so verbocken konnte, ich hab wohl in der Vorlage ausversehen bei += geschaut... jetzt wo ich weiß woran es liegt ist es nur noch peinlich.

Ich werde meinen Kram mal gleich korrigieren, vielen Dank für die Hilfe!

Gruß
Murenius
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
05.08.2008, 17:55 Uhr
murenius



Wunderbar, das addieren/subtrahieren klappt jetzt prima. Aber ich bin gleich auf zwei weitere Newbiefragen gestossen, was die tieferen Weihen von C++ angeht hab ich leider noch nicht viel gemacht.

1) Mein Zuweisungsoperator = macht mir noch sorgen, ist das so richtig?


C++:
Point& operator = (const Point& p)
  {
    if (this != &p)
      for (int i=0; i<d; ++i)
        coord[i] = p.coord[i];
    return *this;
  }



Denn das Gesamtergebnis meines Codes klappt immer noch nicht und dieses Stück code hab ich im Verdacht nicht zu gehen, zumindest deutet im Debugger alles drauf hin.

2) Andere Frage ist zu den Templates... auch da hab ich einfach mal Code kopiert ohne den Background 100% zu verstehen. Kann ich mir damit bös in die Füße schießen, oder reicht es das eben mit "template <int d> class Point" zu definieren und dann einfach innerhalb der Klasse immer wieder d zu benutzen?

Sorry nochmal für die blöden Fragen und danke im Voraus!

Gruß
Murenius
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
05.08.2008, 19:22 Uhr
xXx
Devil


sollte aber korrekt sein ...

C++:
Point& operator= (Point const& rhs)
{
    if (this != &rhs)  std::copy(p.coord, p.coord + d, coord);
    return *this;
}
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
06.08.2008, 08:53 Uhr
stephanw
localhorst



Zitat von murenius:

2) Andere Frage ist zu den Templates... auch da hab ich einfach mal Code kopiert ohne den Background 100% zu verstehen. Kann ich mir damit bös in die Füße schießen, oder reicht es das eben mit "template <int d> class Point" zu definieren und dann einfach innerhalb der Klasse immer wieder d zu benutzen?

Dafür ist der Parameter d da, um benutzt zu werden
--
Reden ist Schweigen und Silber ist Gold.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: