Usare il cast dinamico in C++

Jinku Hu 12 ottobre 2023
Usare il cast dinamico in C++

Questo articolo illustrerà più metodi su come utilizzare il cast dinamico in C++.

Usa dynamic_cast per convertire dal puntatore della classe base a uno derivato

dynamic_cast consente al programmatore di convertire puntatori e riferimenti a classi attraverso la gerarchia di ereditarietà. Ad esempio, è possibile eseguire il cast del puntatore della classe base in un puntatore della classe derivata e consentire al programmatore di chiamare funzioni membro della classe derivata.

dynamic_cast fa parte della funzionalità RTTI (Run-Time Type Information) che fornisce un modo per accedere al tipo di un oggetto in fase di esecuzione invece che in fase di compilazione.

Ricorda che dynamic_cast non può essere usato per convertire tra i tipi primitivi come int o float. Inoltre, si dovrebbe usare solo dynamic_cast quando la classe base contiene almeno una funzione membro virtuale. Nell’esempio seguente, dichiariamo un nuovo puntatore di classe Base e lo lanciamo nel nuovo puntatore alla classe Derived. Poiché dynamic_cast restituisce un puntatore nullo, se il cast non ha successo, possiamo mettere l’espressione nell’istruzione if come condizione.

#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;
}

Produzione:

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

Il programmatore può accedere in sicurezza all’oggetto nell’ambito della sezione if e chiamare i metodi dei membri della classe Derived secondo necessità. Nota, tuttavia, che poiché stiamo trasmettendo il tipo di classe Derivato a Base, sulla tredicesima riga, specifichiamo Derived dopo l’operatore new poiché il seguente codice produrrebbe un cast non riuscito:

#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;
}

L’altra parte della caratteristica RTTI è l’operatore typeid, che restituisce il tipo dell’espressione data. Può essere utilizzato per confrontare tipi di più espressioni, come dimostrato nel prossimo esempio di codice. Nota che l’intestazione <typeinfo> deve essere inclusa quando si usa l’operatore typeid.

#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;
}

Produzione:

Successful cast - can use the pointer to 'Derived' object dp
bp and dp are of same type
Autore: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Articolo correlato - C++ Cast