Cómo usar el reparto dinámico en C++

Jinku Hu 12 octubre 2023
Cómo usar el reparto dinámico en C++

Este artículo demostrará múltiples métodos sobre cómo usar el molde dinámico en C++.

Usar dynamic_cast para convertir el puntero de la clase base en uno derivado

dynamic_cast permite al programador convertir punteros y referencias a clases a través de la jerarquía de la herencia. Por ejemplo, el puntero de la clase base puede ser lanzado en un puntero de clase derivado y permitir al programador llamar a funciones de miembros de clase derivados.

dynamic_cast es parte de la característica Información de tipo en tiempo de ejecución (RTTI) que proporciona una forma de acceder al tipo de un objeto en tiempo de ejecución en lugar de en tiempo de compilación.

Ten en cuenta que dynamic_cast no puede ser usado para convertir entre los tipos primitivos como int o float. Además, sólo se debe usar dynamic_cast cuando la clase base contiene al menos una función de miembro virtual. En el siguiente ejemplo, declaramos un nuevo puntero de clase Base y lo lanzamos en el nuevo puntero de la clase Derivada. Dado que dynamic_cast devuelve un puntero nulo, si el lanzamiento no tiene éxito, podemos poner la expresión en la declaración if como condición.

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

Resultado:

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

El programador puede acceder con seguridad al objeto en el ámbito de la sección if y llamar a los métodos de los miembros de la clase Derivado según sea necesario. Sin embargo, tened en cuenta que como estamos lanzando el tipo de clase Derivado a Base, en la línea 13, especificamos Derivado después de new operador, ya que el siguiente código produciría un lanzamiento infructuoso:

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

La otra parte de la característica RTTI es el operador typeid, que devuelve el tipo de la expresión dada. Puede ser utilizado para comparar tipos de múltiples expresiones, como se demuestra en el siguiente ejemplo de código. Tengan en cuenta que el encabezado <typeinfo> debe ser incluido cuando se usa el operador 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;
}

Resultado:

Successful cast - can use the pointer to 'Derived' object dp
bp and dp are of same type
Autor: 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

Artículo relacionado - C++ Cast