Question

J'ai un tableau de classe objets personnalisés étudiants. CourseStudent et ResearchStudent héritent de l'étudiant, et toutes les instances de l'élève sont l'un ou l'autre de ces derniers.

J'ai une fonction à passer par le tableau, déterminer le sous-type de chaque élève, puis appeler des fonctions membres spécifiques au sous-type sur eux.

Le problème est, parce que ces fonctions ne sont pas surchargées, ils ne se trouvent pas dans des étudiants, de sorte que le compilateur donne le coup d'une agitation.

Si j'ai un pointeur vers l'élève, est-il un moyen d'obtenir un pointeur sur le sous-type de l'étudiant? Est-ce que je dois faire une sorte de casting faux ici pour contourner l'erreur de compilation?

Était-ce utile?

La solution

Vous avez besoin d'un casting dynamique:

Student * s = new ...;    // create student of some sort

if ( ResearchStudent * r = dynamic_cast<ReasearchStudent*>( s ) ) {
   r->ResFunc();
}
else if ( CourseStudent * c = dynamic_cast<CourseStudent*>( s ) ) {
   c->CourseFiunc();
}
else {
   throw "unknown student type";
}

Notez que celui-ci utilise des informations de type maintenu par le compilateur, à condition que la classe a au moins une fonction virtuelle - si tout le reste échoue, faire la destructor virtuelle (comme il se doit dans ce cas anway). Vous devriez toujours préférer cette approche à maintenir vos propres informations de type.

Autres conseils

La meilleure chose serait d'utiliser des fonctions virtuelles:

class Student
{
   // ...
   virtual void SpecificFunction() = 0; /* = 0 means it's abstract; it must be implemented by a subclass */
   // ...
};

class CourseStudent
{
    void SpecificFunction() { ... }
};

Ensuite, vous pouvez faire:

Student *student;
student->SpecificFunction();

A (pire) alternative peut être utilise dynamic_cast:

Student *student;
CourseStudent *cs = dynamic_cast<CourseStudent *>(student);

if (cs) {
   /* student is a CourseStudent.. */
   cs->SpecificFunction();
}

Les fonctions virtuelles ne sont pas appropriées ici parce que les fonctions de membres de la sous-classe sont spécifiques à ces sous-classes (par exemple, le CourseStudent a une liste d'unités, alors qu'un ResearchStudent ne pas, donc une implémentation de la fonction de getUnits () en ResearchStudent n'y aurait aucun sens du tout )

J'ai eu un peu de lecture sur moulages dynamiques et statiques ( cplusplus.com transtypage ), et dans ce cas je pense une distribution statique est plus approprié.

L'inconvénient général d'un static_cast est qu'il ne fonctionne pas toute vérification à l'exécution pour faire en sorte que l'objet moulé à un sous-type est en fait que le sous-type et pas un autre. Dans ce cas, je vérifie spécifiquement le type avant d'effectuer le genre (en utilisant un élément de données privées qui est défini dans le constructeur de sous-classe et n'a pas mutator), aussi longtemps que mon contrôle est bon, il devrait y avoir aucun problème avec une distribution statique . Un casting statique est plus efficace car une distribution dynamique nécessite plus de ressources d'exécution pour effectuer la vérification de type.

Là où il y a une chance d'un membre de ne pas être le type attendu, coulée statique ne serait pas approprié et je voudrais donc aller pour la coulée dynamique (ce qui est une mission donc une fois qu'il a été soumis le code ne sera pas nécessaire de maintenir , donc il n'y a pas de risque d'une personne déconner il plus tard).

Ceci est certainement un cas d'utilisation d'une fonction de membre virtuel pur dans la classe de base, remplaçant alors dans les classes dérivées où vous faites le travail réel.

Vous avez besoin static_cast pour cela. Étant donné que ces fonctions ne sont pas membres virtuels de la classe de base, vous ne pouvez pas les appeler par un pointeur pointeur à la classe de base. Vous devez jeter explicitement le type réel de l'objet.

Ce problème est généralement résolu mieux avec des fonctions virtuelles - vous ne serez pas besoin du type d'objet de vérifier dans votre code plus, aura moins de code et moins de surface pour les bugs

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