Kopierkonstruktor und Zuweisungsoperator mit abstrakter Basisklasse
-
Hallo!
Ich habe folgendes Problem, ich habe eine Klasse (Node) erstellt, die eine rein virtuelle Methode enthält.
Von dieser Klasse habe ich dann eine neue Klasse abgeleitet (DataNode).
Wie funktioniert das jetzt mit dem Kopierkonstruktor (CCtor) und Zuweisungsoperator (AOp)bei der abgeleiteten Klasse bzw. bei deren Basis? Braucht die Basis überhaupt einen CCtor und AOp?
Ich habe die beiden Stellen im Source mit Kommentaren versehen, was das Problem ist. Kann mir da bitte jemand weiterhelfen?
Danke.
class Node { public: explicit Node(Node *child = nullptr, Node *sibling = nullptr); virtual ~Node(); Node(const Node &other); Node &operator=(Node &other); virtual Node* getChild() const; virtual Node* getSibling() const; virtual void setChild(Node *n); virtual void setSibling(Node *n); virtual void printNode(std::ostream &os) const = 0; private: Node *child; Node *sibling; } #include "Node.h" class DataNode: public Node { public: DataNode(int value); virtual ~DataNode(); DataNode(const DataNode &other); DataNode &operator=(DataNode &other); void setValue(int value); int getValue() const; void printNode(std::ostream &os) const; private: int value; }; DataNode::DataNode(const DataNode &other) { // hier hängts, wie initialisiere ich hier child und sibling der Basis? value = other.getValue(); } DataNode &DataNode::operator=(DataNode &other) { if(this != &other) { /* hier sollte ich vermutlich child und sibling löschen * und dann von other zuweisen? Das geht aber nicht, da * die beiden variablen privat sind. */ value = other.getValue(); } return *this; }
-
Stichwort: Initialisierungsliste (Aufruf des Basisklassen-Konstruktors)
DataNode::DataNode(const DataNode &other) : Node(other) { value = other.getValue(); }Und beim Zuweisungsoperator ebenfalls den Basisklassen-Operator aufrufen:
DataNode &DataNode::operator=(DataNode &other) { if(this != &other) { Node::operator=(other); value = other.getValue(); } return *this; }
-
Ohne den Zweck der Klasse zu kennen, wird es keine definitive Antwort geben.
Grundsätzlich lassen sich solche Fragen i.d.R. beantworten, wenn vom Aufruf her gedacht wird.
Die Basisklasse ist abstrakt. Folglich wird einer ihrer Konstruktoren grundsätzlich nur aus dem Konstruktor einer abgeleiteten Klasse aufgerufen werden (was nebenbei bedeutet, dass das explicit bedeutungslos wird).
Ist die Basisklasse in der Lage, mit den Daten, über diese verfügt, allein eine Kopie anzufertigen, sollte das im Kopierkonstruktor passieren (und der abgeleitete Copy-ctor ruft diesen dann auf). Ist eine solche Kopie nicht möglich, wäre der Copy-ctor zweckmäßigerweise zu deleten.Sind virtuelle Funktionen im Spiel, werden Objekte normalerweise per Zeiger oder Referenz angesprochen, und der dynamische Typ stimmt i.d.R. nicht mit dem statischen überein. Unter diesen Umständen sollte auf die Verwendung des Zuweisungsoperators verzichtet werden, da entweder Slicing eintritt oder (bei verwendung virtueller Zuweisungsoperatoren) Typsicherheit aufgegebn wird.
Mithin sollten die Zuweisungsoperatoren in jedem Fall deleted werden.