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
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