Vererbung, Probleme beim access von Daten
-
Hallo,
erstmal fiel mir kein passender Titel ein, sorry dafür. Nun also zum Problem.
Ich habe eine Klasse Instruktion, die einen protected string hat, und 3 Klassen die davon erben, die haben zusätzlich noch 1 int / 2 ints / 2 strings.
In einer anderen Klasse erstelle ich mir dynamisch ein Array von Zeigern von Instruktionen, je nach input werden dann zu den Zeigern dynamisch Objekte der vererbten Klassen zugewiesen.
class Instruction { protected: std::string statement; /* ... */ }; class onevalue : public Instruction { private: int firstvalue; /* ... */ }; class Aprogram { private: Instruction** program; // array of Instruction pointers /* ... */ }; // Auszug aus Aprogram Funktion onevalue* A = new onevalue(instr, first); program[current] = A;Nur will ich z.B. von program[2]->firstvalue haben. Allerdings sagt mir der Compiler, dass die Klasse Instruction kein Wert firstvalue hat. Wie löse ich das Problem, so dass ich ihm sagen kann, dass ich an program[2]->firstvalue rankommen will, wenn ich doch weiss dass es keine Instruktion, sondern ein onevalue ist.
Versteht ihr mein Problem, oder soll cih das noch weiter erläutern?
EInSti
-
Mach eine virtuelle Funktion, die du dann in onevalue überscheibst und den richtigen Wert zurückgibst.
class Instruction { protected: std::string statement; public: virtual int get_firstvalue () const = 0; /* ... */ }; class onevalue : public Instruction { private: int firstvalue; public: int get_firstvalue () const { return firstvalue; } /* ... */ };
-
Entweder castest du (static_cast, dynamic_cast), oder aber du packst die "getter" Funktionen alle mit in die "instruction" Klasse. Bei Instructions die irgendeinen bestimmten Wert nicht haben, kannst du dann entweder den "getter" einen Dummy-Wert zurückgeben lassen, oder eine Exception (z.B: std::logic_error) werfen.
Was zu deinem Vorhaben besser passt kann ich nicht sagen.
Oder natürlich du verzichtest gänzlich auf Polymorphismus, und packst sämtliche möglichen "Teile" in eine struct, und greifst dann direkt darauf zu. Kann auch manchmal Sinn machen.
-
Da wa wohl wer schneller

Ich würde hier aber die Funktion eher nicht pure ("= 0") machen, sondern den "gibt's garnicht" Code (also z.B. Exception werfen) in der Basisklasse als Default-Implementierung anbieten.
Klassen die einen bestimmten Wert dann nicht haben, müssen dann die dazugehörige "getter" Funktion einfach garnicht implementieren. Bei vielen möglichen Werten und vielen möglichen Klassen spart das enorm viel Tipparbeit.
-
hustbaer schrieb:
Da wa wohl wer schneller

Ich würde hier aber die Funktion eher nicht pure ("= 0") machen, sondern den "gibt's garnicht" Code (also z.B. Exception werfen) in der Basisklasse als Default-Implementierung anbieten.
Klassen die einen bestimmten Wert dann nicht haben, müssen dann die dazugehörige "getter" Funktion einfach garnicht implementieren. Bei vielen möglichen Werten und vielen möglichen Klassen spart das enorm viel Tipparbeit.
Ja. War nur ein Denkanstoss. Mir ist danach auch aufgefallen, dass es wahrscheinlich nicht wirklich der Sinn von Instruction sein sollte als solche Basis zu gelten, aber ohne genaueres über die Klasse zu wissen ist das schwer zu entscheiden. Allenfalls wäre es hier auch angebracht eine komplett neue abstrakte Klasse als Basis zu entwerfen, aber das soll ja nicht unsere Entscheidung sein.

-
Die Instruction class ist noch sehr komplex und kann leider nicht abstract gemacht werden. Aber danke für den Tip mit der virtuellen getter funktion, werd es es so machen. Topic kann geclosed werden.