HOWTO · C++

Wie man Dynamic Cast in C++ verwendet

Dieser Artikel führt ein, wie man dynamische Besetzung in C++ verwendet

Auf dieser Seite

In diesem Artikel werden mehrere Methoden zur Verwendung von dynamischem Cast in C++ demonstriert.

Verwenden Sie dynamic_cast, um von einem Basisklassenzeiger zu einem abgeleiteten Zeiger zu konvertieren

dynamic_cast erlaubt es dem Programmierer, Zeiger und Referenzen auf Klassen in der gesamten Vererbungshierarchie zu konvertieren. Beispielsweise kann der Zeiger auf eine Basisklasse in einen Zeiger auf eine abgeleitete Klasse umgewandelt werden, so dass der Programmierer abgeleitete Klassenmember-Funktionen aufrufen kann.

dynamic_cast ist Teil der Run-Time Type Information (RTTI)-Funktion, die eine Möglichkeit bietet, zur Laufzeit statt zur Kompilierungszeit auf den Typ eines Objekts zuzugreifen.

Beachten Sie, dass dynamic_cast nicht verwendet werden kann, um zwischen den primitiven Typen wie int oder float zu konvertieren. Außerdem sollte man dynamic_cast nur verwenden, wenn die Basisklasse mindestens eine virtuelle Memberfunktion enthält. Im folgenden Beispiel deklarieren wir einen neuen Basis-Klassenzeiger und werfen ihn in den neuen Zeiger auf die Derived Klasse. Da dynamic_cast einen Null-Zeiger zurückgibt, können wir den Ausdruck in der if-Anweisung als Bedingung stellen, wenn der Cast erfolglos war.

#include <iostream>
#include <typeinfo>

using std::cout;
using std::endl;

struct Base {
  virtual ~Base() = default;
};

struct Derived : public Base {};

int main() {
  Base *bp = new Derived;
  if (Derived *dp = dynamic_cast<Derived *>(bp)) {
    cout << "Successful cast - can use the pointer to 'Derived' object dp"
         << endl;
  }

  delete bp;
  return EXIT_SUCCESS;
}

Ausgabe:

Successful cast - can use the pointer to 'Derived' object dp

Der Programmierer kann sicher auf das Objekt in der if-Sektion scope zugreifen und bei Bedarf Derived-Klassenmember-Methoden aufrufen. Beachten Sie jedoch, dass wir, da wir den Derived Klassentyp nach Base casten, in der 13. Zeile nach dem new Operator Derived angeben, da der folgende Code einen erfolglosen Cast ergeben würde:

#include <iostream>
#include <typeinfo>

using std::cout;
using std::endl;

struct Base {
  virtual ~Base() = default;
};

struct Derived : public Base {};

int main() {
  Base *bp = new Base;
  if (Derived *dp = dynamic_cast<Derived *>(bp)) {
    cout << "Successful cast - can use the pointer to 'Derived' object dp"
         << endl;
  }

  delete bp;
  return EXIT_SUCCESS;
}

Der andere Teil des RTTI-Merkmals ist der Operator typeid, der den Typ des gegebenen Ausdrucks zurückgibt. Er kann verwendet werden, um Typen von mehreren Ausdrücken zu vergleichen, wie im nächsten Codebeispiel gezeigt wird. Beachten Sie, dass bei der Verwendung des typeid-Operators die Kopfzeile <typeinfo> enthalten sein muss.

#include <iostream>
#include <typeinfo>

using std::cout;
using std::endl;

struct Base {
  virtual ~Base() = default;
};

struct Derived : public Base {};

int main() {
  Base *bp = new Derived;
  if (Derived *dp = dynamic_cast<Derived *>(bp)) {
    cout << "Successful cast - can use the pointer to 'Derived' object dp"
         << endl;
    if (typeid(*bp) == typeid(*dp)) {
      cout << "bp and dp are of same type" << endl;
    }
  }

  delete bp;
  return EXIT_SUCCESS;
}

Ausgabe:

Successful cast - can use the pointer to 'Derived' object dp
bp and dp are of same type