Usar lista dinâmico em C++

Jinku Hu 12 outubro 2023
Usar lista dinâmico em C++

Este artigo irá demonstrar múltiplos métodos de como utilizar o lista dinâmico em C++.

Utilizar dynamic_cast para converter de Ponteiro de Classe Base para Derivado

O dynamic_cast permite ao programador converter apontadores e referências a classes em toda a hierarquia da herança. Como exemplo, o ponteiro da classe base pode ser lançado num ponteiro de classe derivada e permitir ao programador chamar funções de membro de classe derivada.

O dynamic_cast faz parte da funcionalidade Run-Time Type Information (RTTI) que fornece uma forma de aceder ao tipo de objecto em tempo de execução em vez de tempo de compilação.

Lembre-se que o dynamic_cast não pode ser utilizado para converter entre os tipos primitivos como int ou float. Adicionalmente, só se deve utilizar o dynamic_cast quando a classe base contém pelo menos uma função de membro virtual. No exemplo seguinte, declaramos um novo ponteiro de classe Base e lançamo-lo no novo ponteiro para a classe Derived. Uma vez que o dynamic_cast devolve um ponteiro nulo, se o lista não for bem sucedido, podemos colocar a expressão na declaração if como condição.

#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

O programador pode aceder com segurança ao objecto no âmbito da secção if e chamar métodos de membros da classe Derived conforme necessário. Note-se, no entanto, que uma vez que estamos a lançar o tipo de classe Derived para Base, na 13ª linha, especificamos Derived depois do operador new, uma vez que o código seguinte produziria um lista sem sucesso:

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

A outra parte da característica RTTI é o operador tipoid, que devolve o tipo da expressão dada. Pode ser utilizado para comparar tipos de expressões múltiplas, como demonstrado na próxima amostra de código. Note-se que, <typeinfo> cabeçalho deve ser incluído ao utilizar o 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

Artigo relacionado - C++ Cast