Virtual Constructor
-
Hallo, ich schreibe gerade ein kleines Schachspiel, um mein Objektorientiertes Programmieren zu üben ^^
Nun bin ich auf ein Problem gestossen, ich möchte eine abstrakte piece Klasse erstellen und diese dann an die einzelnen Schachfiguren vererben.
Doch, wie kann ich einen virtuellen Konstruktor erstellen? Denn beim erstellen dieser Figuren werden die gleichen Argumente erwartet.
Dankeschön,
samyboy
-
Ein virtueller Konstruktor geht nicht und macht auch wenig Sinn. Beim Erstellen der Instanz musst du den tatsächlichen Typen kennen.
Also schreib in der Basisklasse einen Konstruktor, der seinen Teil initialisiert, und in den abgeleiteten Klassen definierst du neue Konstruktoren, welche den Basisklassenkonstruktor aufrufen.
-
Dankeschön Nexus.
Hab grade gemerkt es ist sowieso eine blöde Idee eine abstrakte piece Klasse für die einzelnen Figuren zu erstellen - wozu auch?
Es stimmt zwar:
rook is a piece
Bringt aber in meinem Fall nix, oder würdest Du, wenn Du ein Schachspiel schreibts eine solche abstrakte Klasse erstellen?
-
typedef bool color; class piece { public: piece(color c) : clr_(c) {} private: color clr_; }; class king : public piece { public: king(color c) : piece(c), zeugs_(0) {} private: kingzeugs zeugs_; };
-
Samyboy schrieb:
Hab grade gemerkt es ist sowieso eine blöde Idee eine abstrakte piece Klasse für die einzelnen Figuren zu erstellen - wozu auch?
Das ist nicht unbedingt eine blöde Idee. Du kannst so die unterschiedlichen Figuren gemeinsam ansprechen. Wenn die Basisklasse zudem polymorph ist, kannst du über sie Aktionen ausführen, die erst in den abgeleiteten Klassen definiert werden.
Ans Beispiel von brotbernd angelehnt:
class Piece { public: // Konstruktor, um Basisklasse zu initialisieren Piece(Color Col, Position Pos); // Virtueller Destruktor nötig bei Polymorphie virtual ~Piece(); // Funktion wird in abgeleiteten Klassen implementiert virtual bool IsMovementValid(Position Dest) = 0; // Normale, nicht-virtuelle Funktion Color GetColor() const; private: Color MyColor; Position MyPosition; }; class King : public Piece { public: // ruft Piece::Piece()-Konstruktor auf King(Color Col, Position Pos); // Prüft Zug spezifisch für König virtual bool IsMovementValid(Position Dest); }; int main() { King k1; // King als Piece ansprechen (Abstraktion, z.B. in // Container von mehreren Figuren) Piece* p = &k1; // Prüft gültigen Zug für König, ohne dass es sich // bei p um eine King-Variable handelt: Dynamische Polymorphie. p->IsMovementValid(Position("B3")); }
-
Öffentliche Vererbung sollte man nur nutzen wenn man das ganze polymorph nutzen möchte, so wie es Nexus gezeigt hat. Ob das bei einem Schachspiel unbedingt nötig ist müsste man noch mal etwas ausführlicher überdenken. Ein Schachspiel beginnt ja eigentlich immer mit der selben Konstellation an Objekten.
Die gezeigte IsMovementValid Geschichte könnte man z.B. auch mit dem Strategy Pattern lösen. Jede Figur würde mit einem unterschiedlichen MovementSolver initialisiert, der für jeden Zug berechnet wo es hingehen kann.Das sind aber nur Anregungen, keine Empfehlungen...