0
votes

Fonction avec des arguments dérivés en C ++

disons que j'ai les classes suivantes: xxx

comme vous le voyez B et c hériter de A et dériveClass1 et dérivéclass2 hérit de BASECLASS .

en raison de mon type de déclaration de fonction Dummy () n'est pas autorisé, car les arguments ont changé, même si B et c sont dérivés de A . < / p>

quelle est la bonne façon de le faire?

Une possibilité serait de laisser les arguments comme ils sont utilisés pour être dans le basoclass et juste faire Casting après dans la fonction mannequin , mais je suppose que ce n'est pas vraiment sympa.

sinon, ne faites pas de dérivation de mannequin (et retirez-le de basoclass ), donc les deux classes dérivéclass1 et dérivéclass2 les déclarent indépendamment. Mais alors l'idée de toutes les classes dérivées de basoclass doit mettre en œuvre du mannequin disparut.


6 commentaires

Quelle est exactement votre question?


Ce n'est pas ce que l'héritage est pour. Si vous avez basoclass * quelque part et que vous souhaitez appeler mannequin , comment savez-vous quel argument devriez-vous passer? a * ? b * ? c * ? Vous devriez repenser votre conception.


DUMMY () IN DERIVECLASS1 et DERIVECLASS2 Sont surcharges (et ils sont autorisés). Un mannequin annuel (A *); serait remplacer .


Considérant la conception de ce que je vois: je pense que ce serait mieux, si la classe de base implémente un membre de A et la classe dérivée crée un type correspondant. Le mannequin est ensuite appelé sans paramètre et peut faire les choses nécessaires. Peut-être que si vous donnez plus de détails, nous pouvons discuter d'une "bonne" solution


J'ai fait un exemple de ce que l'effet serait si vous avez réalisé votre DeriveClass ES concret (au lieu d'abstrait comme ils sont maintenant): ici


Cela ne pourrait-il pas être résolu en faisant basoclass un modèle où a est un argument de type de modèle? (Accordé, vous devez utiliser C ++ 2X pour permettre l'utilisation des contraintes d'argument de type si vous souhaitez vous assurer que T: A ).


4 Réponses :


1
votes

Tout d'abord, lorsque vous déclarez que quelque chose a est une classe de base de B ou C , vous le faites avec l'intention que < Code> B et C avoir toutes les propriétés de A et que vous pouvez utiliser B et c Dans n'importe quel endroit que vous pouvez utiliser A in. Un bon design fournit souvent une définition significative de A qui permet une définition générique de mannequin Pour toutes les spécialisations de A . En ce sens, le problème peut être moins courant que vous ne pouvez vous attendre.

Si vous souhaitez instancier dériveClass1 ou dériveClass2 , votre notion de dérivéclass1 et dérivéClass2 n'a pas vraiment de sens, car pour que soit a basoclass , ils doivent fournir une définition significative de Vide mannequin (a * a) . Vous devez fournir cette définition. Ils peuvent fournir des méthodes factice vides (B * B) ou mannequin vide (C * C) , mais ceux-ci ne sont utilisés que si la statique Type de BASECLASS dériveClass1 ou dériveClass2 .

si dériveClass1 DeriveClass2 doit distinguer entre B et C , cela pourrait être un signe de mauvaise conception. Mais cela pourrait également être une décision bien informée. Généralement, vous avez besoin d'un moyen d'expédier dynamiquement à la bonne méthode. Par exemple, cela pourrait être atteint comme celui-ci: xxx


8 commentaires

Les classes découlant d'une classe abstraite mettent souvent la mise en œuvre de virtuelles pures, mais elles ne sont nullement nécessaires pour le faire. Votre deuxième paragraphe suggère que ce serait le cas.


@ idclev463035818 Fonctions virtuelles pure sont requises pour être remplacées dans une sous-classe non abstraite. Je pense que les gens sont descendus Markus sur une technicité.


@ idclev463035818 aussi, 463035818 n'est pas un numéro de carte IDCLEV valide: p


@Dai sur une sous-classe non abstraite Oui, mais ce n'est pas ce qui est écrit sur ce deuxième paragraphe. Je ne sais pas pourquoi les autres vote, je viens de montrer quelque chose que je pense est une désinformation


@Dai l'avez-vous essayé?


@ idclev463035818 Vous avez raison, bien sûr. J'ai fait l'hypothèse que OP souhaitait instancier DeriveClass1 ou 2 et ceux qui étaient censés être non abstraits. Édité ma réponse pour la clarté.


@ idclev463035818 Je l'ai essayé dans un port WebAssembly non officiel de Doom 2 et rien ne s'est passé :(


@Dai quelle pitty: p. Je ne suis pas content de l'espace de mon pseudo, car Afair pour la triche pour travailler, il n'y avait pas d'espace autorisé, mais je ne voulais plus le changer quand je l'ai réalisé. Désolé d'aller un peu offtopic ...



0
votes

En raison de ma compréhension, ce type de déclaration de fonction factice () n'est pas autorisé

Techniquement, les déclarations indiquées de mannequin sont autorisées. Il se peut toutefois que vous espériez que les enfants soient concrets, ce qui n'est pas le cas.

Sinon, ne faites pas de dérivation de mannequin (et retirez-le de la base de base), de sorte que les deux classes dérivéClass1 et dériveClass2 leur déclarent indépendamment.

Cette approche a du sens.

Mais alors l'idée de toutes les classes dérivées de la base de base doit mettre en œuvre du mannequin disparut.

Ceci est simplement une idée qui ne peut pas être exprimée avec héritage d'une classe de base. Il n'y a pas de concept de "enfant implémente une fonction membre avec certains argument". Le type d'argument doit être connu et tous les enfants doivent accepter tous les arguments que la base accepte. Et cela n'est pas rempli par votre hiérarchie, les enfants restent donc abstraits.

La structure que vous recherchez semble plutôt être concept . C ++ 20 introduira une manière programmatique de spécification de concepts; Jusque-là, les concepts sont implicites: Si vous écrivez un modèle, vous pouvez spécifier qu'un argument de type doit satisfaire à l'exigence d'une fonction de membre mannequin . Les deux types "dérivés" satisferaient ce concept.


0 commentaires

0
votes

Le point de héritage virtuel est que vous pouvez appeler vos classes dérivées via une référence / un pointeur sur le type de base:

void DerivedClass1::dummy(A* a) {
  if (B* const b = dynamic_cast<B*>(a)) {
    /* do stuff with b */
  } else {
    /* error handling -> wrong runtime type */
  }
}


0 commentaires

0
votes

C ++ n'est pas en mesure de gérer votre situation car il n'ya aucun moyen de mettre une telle contrainte sur les appels de fonction par la classe de base. Mais la modification du type de fonction virtuelle peut être effectuée par exemple pour des types retournés, voir Covariance et Contravarariance : xxx


0 commentaires