static_cast sur les classes dérivées lorsque se base à partir de pas polymorphes à polymorphes

StackOverflow https://stackoverflow.com/questions/4012943

  •  26-09-2019
  •  | 
  •  

Question

Je passe en revue C ++ lance opérateur et je doute suivant:

pour les classes polymorphes

  • I je devrais utiliser polymorphic_cast
  • Je ne devrait jamais utiliser de static_cast depuis le bas-casting pourrait mener à un comportement non défini. Le code compile ce cas de toute façon.

Supposons maintenant que je le situtation suivant

class CBase{};
class CDerived : public CBase{};

int main( int argc, char** argv ){
    CBase* p = new CDerived();
    //.. do something
    CDerived*pd = static_cast<CDerived*>( p );
}

Comme il n'y a pas de polymorphisme impliqué, je ne vais pas utiliser polymorphic_cast et le code ne même compiler.

Si à un moment donné, quelqu'un introduit certaines fonctions virtual dans l'arbre d'héritage et je suis maintenant au courant de ce que je suis en danger: comment puis-je réaliser?

Je passer à polymorphic_cast pour éviter tout risque, mais le code compilerons encore sans notification.

Que faites-vous pour réaliser au sujet de ce genre de changements ou de prévenir ces cas?

Merci AFG

Était-ce utile?

La solution

Arrière-plan vous n'avez pas inclus - coup de pouce a polymorphic_cast comme une enveloppe autour dynamic_cast<> qui jette lorsque le sort échoue. static_cast<> est très bien si vous êtes certain que les données sont du type que vous casting à ... il n'y a pas de problème avec ou sans membres virtuels, et le code que vous incluez dire qu'il ne sera pas compilerez compiler et exécuter très bien tels quels.

Je suppose que vous pensez à la possibilité de accidentellement jeté à une autre classe dérivée? C'est l'utilité / risque de coulée, non? Vous pouvez ajouter un destructor virtuel puis utilisez dynamic_cast <>, comme strictement parlant RTTI est uniquement disponible pour les types avec une ou plusieurs fonctions virtuelles.

Le code écrit avec static_cast <> continuera à gérer le même type en toute sécurité quel que soit l'introduction de fonctions virtuelles ... il est juste que si vous commencez à passer ce code d'autres types (non CDerived ou quoi que ce soit publiquement dérivées) alors vous aura besoin du dynamic_cast <> ou un autre changement pour empêcher les opérations incompatibles.

Autres conseils

Alors que vous traitez avec pointeur p (de type CBase *) l'objet pointu sera traité comme un CBase, mais toutes les fonctions virtuelles fera la bonne chose. Pointeur pd traite le même objet en tant que CDerived. Le transtypage ascendant de cette manière est dangereuse, car, si l'objet est dérivé du type upcasted, toutes les données membres supplémentaires pour l'objet upcasted seront manquants (ce qui signifie que vous allez fouiner dans d'autres données), et la recherche de fonction virtuelle sera tout foiré. Ceci est à l'opposé de coulée en descente (que vous avez balisé cette question) où vous pourriez obtenir découpage en tranches .

Pour éviter cela, vous devez changer votre style de programmation. Traiter le même objet que deux types différents est une pratique douteuse. C ++ peut être très bon pour faire respecter la sécurité de type, mais il vous permettra de passer des choses désagréables si vous voulez vraiment, ou tout simplement ne savent pas mieux. Si vous êtes désireux de faire des choses différentes en fonction d'un type d'objet, et ne peut pas le faire à travers des fonctions virtuelles (telles que par à double expédition), vous devriez regarder plus à fond dans RTTI ( regarder ici , ou voir quelques bons exemples ).

polymorphic_cast n'a pas été défini dans C ++. Pensez-vous à dynamic_cast?

De toute façon, vous ne pouvez rien faire pour l'empêcher.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top