PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Objekt mit virtuals als value übergeben == böse?



axeljaeger
04-07-2004, 16:04
Ich habe ein Objekt Curve


class Curve {
public:
void movePoint(const PointList::iterator & p,
double nx, double ny);
void removePoint(const PointList::iterator & p);
protected:
virtual void pointAdded(const Point& ) {}
virtual void pointRemoved(const Point& ) {}
private:
...
}

Dann hab ich noch ein zweites Object Curve Model


class CurveModel : public Curve {
protected:
void pointAdded(const Point&);
void pointRemoved(const Point&);
void pointMoved(const Point&);
};

Ich mache damit öfters solche Sachen:


CurveModel* cm;
Curve c = *cm;

Darf ich das, so lange ich die virtuals nicht aufrufen möchte? Es funktioniert zwar, aber bei C++ weis man nie, ob das jetzt nur zufällig so funktioniert. Mittlerweile kommt es mir sehr abenteuerlich vor. Sollte ich mein Design ändern?

panzi
04-07-2004, 16:54
CurveModel* cm; // = new CurveModel(); !!!!
Curve c = *cm;

Solltest nicht noch ein neues CurveModel erstellen? das ist sonst ein nicht initialisierter Pointer der wer weiß wo hinzeigt.
Und in der zweiten Zeile wird ganz einfach der Curve-Anteil von CurveModel elementweiße kopiert, das funktioniert natürlich.

wraith
04-07-2004, 18:02
Das Problem, das hier auftritt ist unter dem Namen 'slicing' bekannt (falls du noch mehr Informationen dazu suchen solltest).
Und ist etwas was man nicht haben will, daher gibt es verschiedene Maßnahmen, um dieses in gutem Code zu verhindern.

Z.b. Copy-Constructor und Zuweisungsoperator private, kopieren über eine virtuelle Clone Funktion.
Oder Curve wäre abstrakte Klasse (da kein Blatt), und nur Blätter in der Klassenhierachie wären nicht abstrakt (in Java auch noch final).
Bei beiden Varianten gäbe es bereits zur Compilezeit Fehlermeldungen, falls slicing auftritt.

Aber da du esso haben willst, es passiert nicht viel schlimmes (siehe panzi).

axeljaeger
05-07-2004, 10:02
Solltest nicht noch ein neues CurveModel erstellen?
Ja, mache ich an anderer Stelle. Aber ich verlasse mich jetzt mal auf Wraith und dich, dass generell nichts böses passiert. Gibt es bei der Performance Unterschiede, wenn ich ein Objekt mit virtuals kopiere? Es wird wohl drauf hinauslaufen, dass CurveModel nicht mehr von Curve erbt, sondern ein Curve als Member hat und die enstprechenden Methoden forwarded und es eine Methode curve() geben wird, mit dem an die Daten kommt.