Passer les sous-classes d'une fonction qui prend leur super-classe
Disons que j'ai trois classes - Animal
, Cat
et Dog
, où Cat
et Dog
sont des sous-classes de Animal
(cela ne sonne comme la première des conférences, mais ce n'est pas de devoirs, je le promets, tout en simplifiant le code réel)
Dog* spike = new Dog();
Cat* puss = new Cat();
int main(int argc, char** argv)
{
function(spike, puss);
return 0;
}
void function(Animal *pet, Animal *pet2)
{
magic->andSoForth();
}
Maintenant cela génère l'erreur suivante:
Cannot convert parameter 1 from 'Dog *' to 'Animal'
No constructor could take the source type,
or constructor overload resolution was ambiguous
De changer les paramètres pour correspondre exactement génère des erreurs similaires, mais seulement qu'il dit qu'il ne peut pas convertir à partir d'une classe à la même classe.
J'ai appelé avec succès les fonctions de sous-classes et les membres qu'ils héritent de la classe mère, donc je sais que ce qui, logiquement, devrait fonctionner. Je ne sais pas dans quel tordu de manière à ce langage envie de me plier à la logique.
MODIFIER
Solution arrive d'être: les pointeurs de confondre tout le monde.
- Déclarer des pointeurs.
- Envoyer des pointeurs comme des arguments à une fonction qui ne gère PAS les pointeurs.
Dans mon exemple, j'ai envoyé le "pas de pointeurs" à la fonction qui voulait les pointeurs, j'ai tout juste de passer. Maintenant, il fonctionne très bien.
Dog spike
mais ensuite été modifié pour Dog* spike
. C'était probablement erronée au début, mais vu la code incorrect dans la question est essentielle pour comprendre la différence entre elle et corriger le code dans la réponse. Quelqu'un peut-il expliquer pourquoi de ce changement qui s'est passé et a été la meilleure réponse donnée fondées sur elle ou sur la première version de la question?OriginalL'auteur XistenZ | 2012-12-02
Vous devez vous connecter pour publier un commentaire.
Lorsque vous allouer dynamiquement un nouvel objet, vous obtenez un pointeur vers cet objet. Si vous avez besoin de le stocker dans un pointeur comme suit:
Vous pouvez ensuite passer
spike
oupuss
pour n'importe quel paramètre de typeAnimal*
, en supposantDog
etCat
en effet hériter deAnimal
. C'est la base du polymorphisme en C++:Vous pouvez, bien sûr, d'avoir stocké immédiatement comme
Animal*
:N'oubliez pas de
delete
. Mieux encore, ne pas utiliser denew
à tous:Ajouter à votre question, le code et la ligne de l'erreur, dit-il correspond à l'.
Votre montage ne permet pas d'expliquer ce que vous avez fait pour le résoudre. Montrer ce qui n'allait pas et le code qu'il fixe. Aussi, mettre la réponse dans ta réponse, non pas dans la question. 🙂 Merci
OriginalL'auteur Joseph Mansfield
C'est raisonnable à supposer que le problème que vous avez est l'affectation d'un pointeur à un non-pointeur, ou vice versa. Mais votre code n'est pas le vrai code, et vos messages d'erreur sont apparemment pas le réel les messages d'erreur. Donc, c'est toutes les conjectures, en particulier ceux déjà posté des réponses que de dire "c'est elle" (c'est probablement le cas, mais pas nécessairement, et l'incertitude est entièrement de votre faute).
EDIT: l'OP a changé la question du code de 10 secondes après que j'ai posté ce.
Le code ne fonctionne toujours pas en place avec le prétendu message d'erreur.
Je ne vais pas chasser cette question que cela change.
Maintenant, quoi faire...
Ne pas utiliser
new
.Connu les programmeurs en C++ utilisent parfois
new
contrôlés manières, enveloppés dans des code. Incompétent programmeurs C++ utilisent souventnew
comme une question de cours. Mais en général, vous n'en avez pas besoin, et c'est problématique, afin de mieux comme défaut de ne pas l'utiliser.Ensuite, votre programme (que vous avez négligé de montrer) devrait ressembler à ceci:
Mais plus laide? Je suis toutes les oreilles (un Indice: "C++" != "C#", même pas
string.Equals("C++", "C#", StringComparison.UniversalPolyglotIgnoreInterpunction)
)Ils sont, pour tous les détails significatifs de fins, entièrement identiques aux classes.
Je ne sais pas quelles sont vos sources, mais rassurez-vous, les structures sont aussi laid que les classes sont. La seule différence entre les deux est que l'on a visibilité publique par défaut, et l'autre privé.
En C++, struct classes. Littéralement, la seule différence entre une structure et une classe sont le défaut de visibilité (publique pour les structures) et l'utilisation de
struct
plutôt queclass
de déclarer le type. À tous autres égards, ils sont identiques. Même héritage, des fonctions virtuelles, et tout ce qui chic choses; les structures peuvent aussi, à l'identique.OriginalL'auteur Cheers and hth. - Alf
Votre prototype pour
function
presque certainement ditou quelque chose de très semblable. (Je sais que vous avez un prototype, depuis
function
apparaît aprèsmain
. Si vous n'aviez pas de l'avant-déclarée, C++ puisse se plaindre qu'il ne trouve pasfunction
à tous, pas que c'est prendre les mauvais types d'arguments.)Problème, c'est votre vrai
function
prend des pointeurs. Et depuismain
apparaît avant le vraifunction
, il ne voit pas que. Il ne voit que la déclaration de celui qui prend la réelleAnimal
s, il tente de l'utiliser...mais ne parvient pas, parce que l'Animal pointeur n'est pas un Animal. (Le vraifunction
à la différence du prototype est bien avec le C++, en raison de la possibilité de surcharger. Aussi loin que le compilateur sait,function(Animal, Animal)
existe dans une autre unité de traduction, et vous êtes tout simplement la définition defunction(Animal*, Animal*)
trop.)Regarder à travers votre code pour la déclaration de
function
, et de lui faire direà correspondre avec la fonction réelle de la signature.
PS: cela aurait été beaucoup plus facile à comprendre si vous avez inclus toutes les déclarations pertinentes.
PPS: UNE meilleure idée serait de prendre des références au lieu de cela, comme suggéré par Alf. Mais pour le faire de toute façon, vous auriez à fixer le prototype d'incompatibilité (ou de faire de la vraie fonction apparaissent avant le code qui l'utilise) première
OriginalL'auteur cHao
Bien, ce que vous devez faire est de cette
Fondamentalement, tout le pointeur de la souris définitions doivent être de la classe de base, et ceux-ci peuvent être initialisées avec une classe dérivée de pointeurs.
new
retourne pointeurs).Voulez-vous dire
Animal *spike
?Désolé, c'est Animal * Spike, mon erreur, j'ai édité, en maintenant..Merci @Xymostech
OriginalL'auteur Nicomoto
C'est comment il devrait ressembler.
Testé et de travail.
pet2
est unCat
. Dans ce cas, il n'est pas une affaire énorme, parce que les animaux ne sont pas réellement faire beaucoup, si quoi que ce soit. Mais plus tard, quand unCat
comprend des comportement et des propriétés, ou si vous voulez un écureuil loin dans un vecteur ou quelque chose, vous ferez l'expérience du "découpage" du problème de première main. La bonne réponse consiste à comprendre pourquoi le pointeur de la version de pauses; il ne devrait pas être aussi compliqué que vous faites.Ou, en déclarant la fonction pour prendre des références. Ce serait mieux que des pointeurs, mais n'est toujours pas résolu la raison pour laquelle vous êtes actuellement coincé en passant
Animal
s par valeur. Et vous devez comprendre cela; avec le C++, vous n'obtenez pas de polymorphisme, sauf si vous avez accès à un objet par l'intermédiaire d'un pointeur ou d'une référence. Sans polymorphisme, les sous-classes deviennent plutôt inutile.OriginalL'auteur XistenZ