2017-09-01 7 views
1

J'ai le code suivant.Le pointeur dérivé vers la conversion du pointeur de base à l'aide de static_cast, dynamic_cast ou de la conversion explicite n'appelle pas la fonction de base

#include <iostream> 
using namespace std; 


class Base 
{ 
public: 
    virtual int f(){cout<<"Base"<<endl;} 
}; 

class Derived:public Base 
{ 
public: 
    int f(){cout<<"Derived"<<endl;} 
}; 

int main() 
{ 
    Base b; 
    Derived d; 

    b.f(); ///base 
    ((Base)d).f(); ///base 

    cout<<"----------------"<<endl; 

    Base *b1 = new Base; 
    Base *b2 = new Derived; 
    Derived *d1 = new Derived; 

    b1->f(); ///base 
    ((Base*)d1)->f(); ///derived 
    ((Base*)b2)->f(); ///derived 
    static_cast<Base*>(d1); 
    d1->f();///derived 
    static_cast<Base*>(b2); 
    b2->f();///derived 

    cout<<"----------------"<<endl; 

    Base *b5 = dynamic_cast<Base*>(b2); 
    Base *b6 = dynamic_cast<Base*>(d1); 
    if(b5) 
     b5->f(); ///derived 
    if(b6) 
     b6->f(); ///derived 


    return 0; 
} 

Je veux demander pourquoi les dérivés * d1 OU pointeurs b2 lorsqu'il est converti en une base en utilisant transtypage explicite (base), fonte statique (static_cast (d1)) ou coulée dynamique (dynamic_cast (d1)) n'appellera pas la fonction f() de la classe de base après la conversion. Il semble appeler la fonction f() de la classe dérivée à chaque fois.

Aussi, étrangement, quand je déclare les objets de cette façon. La conversion fonctionne et appelle la fonction de base.

Base b; 
    Derived d; 

    b.f(); ///base 
    ((Base)d).f(); ///base 

Maintenant, je compris que la bonne façon d'accéder à la f() de la classe de base serait d->Base::f(), mais pourquoi devrais-je utiliser dynamic_cast ou static_cast car ils ne convertit pas le pointeur dérivé à la base et appeler le bonne fonction. J'aurais besoin d'une explication détaillée si possible. Merci!

+1

'dynamic_cast' est utilisé pour la base coulée de dérivés, ce qui pourrait échouer. Dérivé à la base fonctionne toujours, et n'a pas besoin de moulage. –

+0

Merci Bo, j'apprécie votre explication. –

Répondre

1

Heureusement, pour vous et mon clavier, l'explication est trivial:

((Base)d)tranches l'objet d à une valeur copiée Base par exemple.

((Base*)d1)->f() va encore appeler la méthode dérivée depuis Base et donc Derived sont les types polymorphes, et bien que ((Base*)d1) est un pointeur Base*, il pointe vers un objet Derived. Idem pour static_cast et dynamic_cast.

Référence: https://en.wikipedia.org/wiki/Object_slicing