Dynamic_cast — Wikipedia

before-content-x4

A wikipedia article, free l’encyclopéi.

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:

after-content-x4
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 ]

On other Wikimedia projects:

external links [ modifier | Modifier and code ]

after-content-x4