2008-08-26 18 views

Répondre

0

Mon projet de jouet utilise deux fois dynamic_cast; une fois pour contourner l'absence de répartition multiple en C++ (c'est un système de type visiteur qui pourrait utiliser plusieurs dispatch au lieu des dynamic_casts), et une fois pour spécial-cas un sous-type spécifique.

Les deux sont acceptables, à mon avis, même si la première provient au moins d'un déficit de langage. Je pense que cela peut être une situation courante, en fait; La plupart des dynamic_casts (et un grand nombre de "patterns design" en général) sont des solutions de contournement pour des défauts de langage spécifiques plutôt que pour quelque chose qui vise.

0

Il peut être utilisé pour un peu de sécurité de type à l'exécution lors de l'exposition de poignées à des objets via une interface C. Toutes les classes exposées héritent d'une classe de base commune. Lorsque vous acceptez un handle pour une fonction, lancez-la dans la classe de base, puis lancez la distribution dynamique dans la classe que vous attendez. Si elles sont passées dans un handle non-sensical, vous obtiendrez une exception si le run-time ne trouve pas le rtti. S'ils ont passé un handle valide du type incorrect, vous obtenez un pointeur NULL et pouvez lancer votre propre exception. S'ils sont passés dans le bon pointeur, vous êtes prêt à partir. Ce n'est pas infaillible, mais il est certainement préférable d'intercepter des appels erronés aux bibliothèques qu'un réinterprétation directe à partir d'un descripteur et d'attendre que certaines données soient mystérieusement corrompues lorsque vous transmettez la mauvaise poignée.

1

Voici quelque chose que je fais souvent, ce n'est pas joli, mais c'est simple et utile.

Je travaille souvent avec des conteneurs de modèles qui mettent en œuvre une interface, imaginer quelque chose comme

template<class T> 
class MyVector : public ContainerInterface 
... 

Où ContainerInterface a des choses utiles de base, mais c'est tout. Si je veux un algorithme spécifique sur les vecteurs d'entiers sans exposer mon implémentation de modèle, il est utile d'accepter les objets d'interface et de les mettre en dynamique vers MyVector dans l'implémentation. Exemple:

// function prototype (public API, in the header file) 
void ProcessVector(ContainerInterface& vecIfce); 

// function implementation (private, in the .cpp file) 
void ProcessVector(ContainerInterface& vecIfce) 
{ 
    MyVector<int>& vecInt = dynamic_cast<MyVector<int> >(vecIfce); 
    // the cast throws bad_cast in case of error but you could use a 
    // more complex method to choose which low-level implementation 
    // to use, basically rolling by hand your own polymorphism. 

    // Process a vector of integers 
    ... 
} 

Je pourrais ajouter une méthode Process() à la ContainerInterface qui serait résolu polymorphically, ce serait une méthode plus agréable POO, mais je préfère parfois le faire de cette façon. Lorsque vous avez des conteneurs simples, beaucoup d'algorithmes et que vous voulez garder votre implémentation cachée, dynamic_cast offre une solution facile et laide.

Vous pouvez également examiner les techniques de double expédition.

HTH

0

Eh bien, ce serait vraiment agréable avec des méthodes d'extension en C#. Par exemple, disons que j'ai une liste d'objets et que je veux obtenir une liste de tous les identifiants d'eux. Je peux les parcourir tous et les sortir, mais je voudrais megmenter ce code pour le réutiliser.

donc quelque chose comme

List<myObject> myObjectList = getMyObjects(); 

List<string> ids = myObjectList.PropertyList("id"); 

serait cool, sauf sur la méthode d'extension, vous ne saurez pas le type qui vient dans.

Alors

public static List<string> PropertyList(this object objList, string propName) { 
    var genList = (objList.GetType())objList; 
} 

serait génial.

9

Cette discussion récente donne un exemple d'où elle est pratique. Il existe une classe Shape de base et des classes Circle et Rectangle dérivées de celle-ci. En testant l'égalité, il est évident qu'un Cercle ne peut pas être égal à un Rectangle et ce serait un désastre d'essayer de les comparer. Pendant l'itération à travers une collection de pointeurs vers des formes, dynamic_cast fait double emploi, vous indiquant si les formes sont comparables et vous donnant les objets appropriés pour faire la comparaison.

Vector iterator not dereferencable

0

Il est très utile, cependant, la plupart du temps, il est trop utile: si pour faire le travail le plus simple est de faire un dynamic_cast, il est le plus souvent un symptôme de mauvaise conception OO, ce qui à son tour pourrait conduire à des problèmes dans le futur de manière imprévue.