Vererbung von operator=
-
Ja, das Beispiel ist etwas zu simple. Der Operator macht mehr als einfach nur Daten zu kopieren und muss daher überschrieben werden.
Ich dacht halt, wenn ich kind=mutter machen, dann wird automatisch der Operator der Mutter genommen.
-
Nein, wird er nicht - das geht nur in der anderen Richtung
m=k;(oder wenn du explizit einen operator= definierst).PS: Es ist zwar nicht wirklich vom Standard vorgeschrieben, aber üblicherweise sieht ein op= so aus:
class Typ { public: Typ& operator=(const Typ& other) { //eigentliche Zuweisung //achte auf mögliche Selbstzuweisungen return *this; } }(auf diese Weise kannst du auch Zuweisungsketten (
a=b=c=somedata;) verwenden und du sparst dir eine Kopier-Operation)
-
Okay, danke! Wieder was gelernt... Ich hab nun allen abgeleiteten Klassen ihren eigenen Operator gegeben und alles ist gut.
-
Denkst du zumindest *scnr*
Für den Moment mag ja der Compiler glücklich sein und dein Programm funktionieren. Aber ob dein Programm wirklich das macht, was es soll, steht auf einem anderen Blatt.
Beispiel gefällig:
class base { public: base& operator=(const base&); ... }; class kind1 : public base { int m_value; public: kind1& operator=(const base& other) { base::operator=(other);// base-Anteil kopieren m_value = 0; // eigene Anteile nicht verfügbar - Defaultwert verwenden return *this; } }; class kind2 : public base {/* analog aufgebaut */}; int main() { kind1 k1; kind2 k2; k2=k1; }Normalerweise sollte die letzte Anweisung scheitern, aber durch den eigenen operator= funktioniert das (k1 wird in ein base-Objekt umgewandelt und zugewiesen) - jetzt mußt du überlegen, ob das der Sinn der Sache ist.
PS: Kannst du mal grob umreißen, was du vorhast? Womöglich hat du ja schon im Ansatz des Klassendesigns einen Denkfehler eingebaut.
-
littlejohn schrieb:
..
<- hier hacktsWer hackt ?
"....
I cut down trees, I eat my lunch,
I go to the lavat'ry.
On Wednesdays I go shopping
And have buttered scones for tea.
..."Gruß,
Simon2.
-
CStoll schrieb:
Nein, wird er nicht - das geht nur in der anderen Richtung
m=k;...... und das deswegen, weil so kein "halbdefiniertes Ergebnis" zurückbleibt.
(Das Argument, dass der Mutter::operator=() nicht die zusätzlichen Kind-Attribute füllen kann, bleibt einfach bestehen).
Beispiel (nur für diesen Zusammenhang, nicht für "perfekten Code")class Mutter { protected: int a; public: virtual void seta(int i) { a = i; } .... } class Kind : public Mutter { int b; public: virtual void seta(int i) { Mutter::seta(i); b = 4*i; } ... };Wenn jetzt nur "die Mutterteile" (Mutter::a -> Kind::Mutter::a) kopiert würden, hätte man in einem Kind a und b inkonsistent....
Dagegen kann man durchaus konsistent Kind::Mutter::a auf Mutter::a kopieren.Gruß,
Simon2.
-
Also was ich mir da gedacht hab ist folgendes:
Ich hab einen Interpreter und der hantiert mit einer Klasse namens "Union" herum. Diese hat Funktionen und Daten. Wenn der Interpreter fertig ist mit abarbeiten gibt er das Ergebnis der letzten Operation aus und zwar in Form einer solchen "Union". Damit diese von aussen besser handhabbar wird, leite ich davon Klassen ab, z.b. "UnionTools". Diese Klasse hat noch ein paar Funktionen, die innerhalb der Interpreters nicht benutzt/gebraucht werden.
das sieht dann ungefähr so aus:
Union Interpret() {...} UnionTools o = Interpret( "..." );Die Union enthält nicht nur integer oder strings sondern kann auch weitere Unions enthalten. Daher wollte ich da noch ein paar Funktionen ranbauen um besser mit dem Ergebniss umgehen zu können.
Ist die Idee schlecht? Wenn ja, was wäre ein besserer Ansatz?
-
und jetzt wirds richtig kompliziert. Das mit den operatoren funktioniert soweit wunderbar, aber der Kopierkonstruktor macht nicht was er soll:
Das ist die Klasse:
/** * copy contructor */ Chess44Man::Chess44Man( const CMScriptDataUnion &o ) { CMScriptDataUnion::CMScriptDataUnion( o ); } void Chess44Man::operator=( CMScriptDataUnion o ) { CMScriptDataUnion::operator=( o ); }und das die Zuweisung:
CMScriptDataUnion oUnion( 100 ); Chess44Man oMan = oUnion; //Variante I: wird ausgeführt, bringt aber nichts oMan = oUnion; //Variante II: wird korrekt ausgeführtAlso Variante I wird korrekt ausgeführt und wenn ich mit dem Debugger reingucke wird auch der Code der Kopierkonstruktors ausgeführt. Danach ist "oMan" allerdings "leer", also die zugewiesenen Daten sind wieder vergessen.
Bei Variante II ist hinterher alles so wie es soll.
Woran liegt das?
-
Wie Scott Meyers sagt: Mache Basisklassen abstrakt!
-
Danke!