Dynamic_cast — Wikipedia
A wikipedia article, free l’encyclopéi.
For homonymous articles, see Dynamic.
In the C ++ programming language, the operator dynamic_cast
is a member of the Run-Time Information (RTTI) system that performs a type conversion. However, unlike the cast inherited from the C language, a verification of the type is carried out at execution, and will raise either an exception in the case of references, or a zero pointer in the case of pointers, if the types are not compatible. SO, dynamic_cast
behaves more like a type converter in a language such as Java, rather than a conversion in the sense of the C language, which does not check anything to execution.
Or a class A
, inherited by B
. Suppose a method takes an object of type A
in argument, which would carry out some additional treatments if the object is in fact a type B
. This can be done using dynamic_cast
as following :
#include // Pour std::bad_cast #include // for std :: cerr, etc. class A { public : // since RTTI is included in the table of virtual methods (the vable), // There should be at least a pure virtual function. virtual void foo () = 0 ; // autres membres... };
class B : public A
{
public:
void foo() { /* ... */ }
void methodSpecificToB() { /* ... */ }
// autres membres...
};
void my_function(A& my_a)
{
try
{
B& my_b = dynamic_cast<B&>(my_a);
my_b.methodSpecificToB();
}
catch (const std::bad_cast& e)
{
std::cerr << e.what() << std::endl;
std::cerr << "Cet objet n'est pas de type B" << std::endl;
}
}
An equivalent version of my_function
can be written with use of pointers instead of references:
void my_function ( A * my_a ) { B * my_b = dynamic_cast < B *> ( my_a ); if ( my_b ! = nullptr ) my_b -> methodSpecificToB (); else std::cerr << "Cet objet n'est pas de type B" << std::endl;
}
To fully understand its functioning, we can look at how the dynamic_cast Maybe manually implemented.
#include // for std :: cerr, etc. class B ; class C ; class A { /// The method that will allow you to know the complete type of our object virtual const char get_type_for_dynamic_cast () const = 0 ; public:
B* dynamic_cast_to_B()
{
if (get_type_for_dynamic_cast() != 'B')
return 0;
return static_cast<B*>(this);
}
C* dynamic_cast_to_C()
{
if (get_type_for_dynamic_cast() != 'C')
return 0;
return static_cast<C*>(this);
}
};
class B : public A
{
int data;
const char get_type_for_dynamic_cast() const { return 'B'; }
public:
B(int data) : data(data) { }
void methode() { std::cout << data << "n"; }
};
class C : public A
{
char* data;
const char get_type_for_dynamic_cast() const { return 'C'; }
public:
C(char* data) : data(data) { }
void methode() { std::cout << data << "n"; }
};
void ma_fonction(A* a)
{
if (B* b = a->dynamic_cast_to_B())
b->methode();
else if (C* c = a->dynamic_cast_to_C())
c->methode();
else {
// erreur de type
}
}
We see that in memory, if our classes already have a vable, the cost is almost zero since we have just added a method in the vable of each of the classes. In terms of calculation time, the cost remains fairly low: a normal castor casting requires no calculation, while here we must call a pure virtual method (which must be read in the vable) and study your return value.
Related articles [ modifier | Modifier and code ]
external links [ modifier | Modifier and code ]
Recent Comments