/ / ist implizites Downcasting mit neuem OK? - C ++, Vererbung, neuer Operator, abgeleitete Klasse, Downcast

ist implizite Downcasting mit neuen OK? - c ++, Vererbung, neuer Operator, abgeleitete Klasse, Downcast

Was halten Sie von diesem C ++ - Code:

Polygon* p;
if(shape=="Rectangle")
p = new Rectangle();
else if(shape=="Triangle")
p = new Triangle();
else
exit(EXIT_FAILURE);

wobei Rechteck und Dreieck von einem Polygon der Basisklasse abgeleitet werden.

Die Idee dahinter ist, dass ich spezifisch verwenden mussMethoden aus den abgeleiteten Klassen, ohne zu wissen, welche Klasse ich brauche, bis das Programm ausgeführt wird. Gibt es einen besseren Weg, dies zu tun? Es wird zwar kompiliert, aber ich frage mich, ob der Destruktor der ausgewählten abgeleiteten Klasse aufgerufen wird, damit die spezifischen Variablen ordnungsgemäß freigegeben werden.

Nebenfrage: umfasst eine Dynamic_cast-Operation eine Datenkopie?

Vielen Dank :)

BEARBEITEN:

Vielen Dank für all diese sehr lehrreichen Antworten.

Nun sagen wir die Methode

bool isIsosceles()

ist in Triangle implementiert, aber nicht in Rectangle.

Dann gleich anrufen

p->isIsosceles()

würde offensichtlich scheitern.

Meine ersten Ideen wären entweder:

Deklarieren und implementieren Sie isIsosceles () als virtuelle Methode in der Basisklasse Polygon als

virtual bool isIsosceles()
{
cout << "Isosceles means nothing to me." << endl;
exit(EXIT_FAILURE);
}

oder die Verwendung von dynamic_cast in einer if-Anweisung.

Ist eine dieser Optionen hier eine gute Praxis?

Danke vielmals

Antworten:

1 für die Antwort № 1

Funktioniert, wenn Sie sich daran erinnern delete p und der Zerstörer von Polygon ist virtual. Das ist wichtig.

Eine bessere Alternative ist das Einpacken in einen Smart Pointer.


1 für die Antwort № 2

Ist implizites Downcasting mit neuem OK?

Es gibt hier kein "Downcasting": Dies ist eine einfache Verwendung von polymorphem Verhalten. Ihre Polygon * ist ein Zeiger auf eine Basisklasse; Ihr Konstruktionscode erzeugt ein Objekt, das die Implementierung durch die Verwendung von virtuellen Memberfunktionen abstrahiert.

Es wird zwar kompiliert, aber ich frage mich, ob der Destruktor der ausgewählten abgeleiteten Klasse aufgerufen wird, damit die spezifischen Variablen ordnungsgemäß freigegeben werden.

Vorausgesetzt, dass der Destruktor in der Basisklasse virtuell ist (was es sein sollte), wird die Freigabe des Objekts über den Basisklassenzeiger alles richtig machen:

delete p;

Gibt es einen besseren Weg, dies zu tun?

Du könntest benutzen std::unique_ptr<Polygon> um den Löschvorgang zu automatisieren Polygon Objekt. Die Verwendung eines intelligenten Zeigers würde das Objekt zerstören, wenn der Zeiger seinen Gültigkeitsbereich verlässt.

Tut ein dynamic_cast Vorgang beinhaltet eine Datenkopie?

Ich gehe davon aus, dass Sie keine Verwendung für haben dynamic_cast hier, weil Polygon deklariert virtuelle Memberfunktionen für alle interessierenden Operationen. Allerdings, wenn Sie es tun dynamic_castEs werden keine Daten kopiert. Das System prüft, ob die Besetzung zulässig ist, und gibt entweder einen ordnungsgemäß umgesetzten Zeiger zurück oder gibt einen zurück nullptr.


0 für die Antwort № 3

Dies ist kein Downcasting. Sie verwenden hier eigentlich Polymorphie, d. H. Sie erstellen ein Objekt eines abgeleiteten Typs, das Sie als Objekt ihres Basistyps verwenden.

Sie können das tun, aber wie bei allem, was Sie mit new zuordnen, verwenden Sie delete. Eine weitere Sache ist, dass Sie einen virtuellen Destruktor in benötigen Polygon, so wie das:

class Polygon {

virtual ~Polygon();
}

Andernfalls werden Sie mit dem Slicing von Objekten enden, dh Sie haben Objekte "halb gelöscht".

Zusätzliche Anmerkung: Zu Ihrer Information würde Downcasting unter Verwendung Ihrer Klassen Folgendes tun:

Polygon* polygon = new Triangle();

Triangle* triangle = dynamic_cast<Triangle*>(polygon);

// Check that we effectively had a triangle under this polygon pointer
if(triangle){
//do something with the triangle
}

0 für die Antwort № 4

Die Idee dahinter ist, dass ich bestimmte Methoden der abgeleiteten Klassen verwenden muss, ohne zu wissen, welche Klasse ich benötige, bis das Programm ausgeführt wird.

Dadurch wird der Zweck des Polymorphismus vereitelt, so dass Sie Operationen ausführen können, OHNE zu wissen, mit welchem ​​abgeleiteten Typ Sie arbeiten.

Gibt es einen besseren Weg, dies zu tun?

Das hängt davon ab, was Sie tatsächlich versuchenin erster Linie erreichen. Was Sie gezeigt haben, kann beispielsweise als Teil einer Klassenfabrik implementiert werden. Sie haben jedoch nicht gezeigt, wie Sie diese Objekte verwenden, nachdem Sie sie erstellt haben. Daher ist es schwer zu sagen, ob Sie das Richtige tun oder nicht.

Ich frage mich, ob der Destruktor der ausgewählten abgeleiteten Klasse aufgerufen wird, damit die spezifischen Variablen ordnungsgemäß freigegeben werden.

Es wird nur wenn ~Polygon() wird als deklariert virtual.

beinhaltet eine dynamic_cast-Operation eine Datenkopie?

Nein. A dynamic_cast führt einfach eine Laufzeitsuche durch, um einen Zeiger auf einen anderen Abschnitt des VMT für dasselbe Objekt zu erhalten.