Remplacement de la fonction et surcharge en C ++ et Delphi
Spacesoft 【sable de nuit sombre】
Dans la programmation orientée objet, lorsque la sous-classe poursuit les fonctions de la classe de base, la sous-classe peut avoir besoin de gérer certaines des fonctions différemment de la classe de base, telles que:
classe Chuman
{
publique:
void saymyname () // imprime le nom de l'objet
{
cout << Salut, je suis un humain << endl;
}
};
Ensuite, il est évident, si sa sous-classe a une fonction saymyName avec le même nom, le même paramètre et la même valeur de retour (une phrase, la même fonction), quelle fonction appellera-t-elle? Par exemple, il y a une classe CMARK maintenant
Classe CMARK: Public Chuman
{
publique:
void saymyname ()
{
cout << salut, je suis mark << endl;
}
};
Ensuite, nous devons demander le segment du programme suivant:
Chuman * Ph = new cmark;
si (pH)
Ph-> SayMyName ();
autre
Cout << Erreur de coulée! << endl;
Supprimer le pH;
pH = null;
Est le salut, je suis Mark que nous voulons imprimer?
Non. Il sort Salut, je suis un humain. C'est horrible, et quand nous pointez une personne et lui demandons de dire son nom, il nous dit qu'il est "une personne" plutôt que de dire son nom. La raison de ce problème est que le pointant de la classe dérivée du public avec le pointeur de classe de base, vous pouvez accéder aux fonctions membres de la classe dérivée qui continuent de la classe de base. Mais s'il y a des fonctions avec le même nom dans la classe dérivée, le résultat accéde à la fonction du même nom de la classe de base, plutôt que la fonction de la classe dérivée elle-même. En fait, ce que nous voulons, c'est déterminer lequel de ces fonctions du même nom doit être appelé par le type réel d'un objet, c'est-à-dire qu'une telle résolution est dynamique. Ou nous pouvons dire que lorsqu'un objet est un sous-type, son implémentation du même nom dans la sous-classe remplace l'implémentation de la classe de base.
Commençons par le traitement par C ++ de ce problème.
Il s'agit d'un exemple typique de polymorphisme dans C ++. Pour être spécifique, il s'agit d'utiliser des mots clés virtuels pour décrire la fonction comme une fonction virtuelle.
classe Chuman
{
publique:
virtual void saymyname () // imprime le nom de l'objet
{
cout << Salut, je suis un humain << endl;
}
};
De cette façon, d'autres codes sont toujours les mêmes, mais notre CMARK sait déjà dire son nom. Peu importe que la fonction SaymYName () de CMARG ait ajouté un mot clé virtuel, car selon les dispositions de la syntaxe C ++, car il remplace la fonction chuman du même nom, il devient virtuel lui-même. Quant à savoir pourquoi un mot clé virtuel a un effet magique si magique? C ++ FAQ Lite explique cela comme suit: En C ++, "Les fonctions des membres virtuels sont déterminées dynamiquement (au moment de l'exécution). Le type de pointeur / référence à cet objet ". Donc, notre pH constate qu'il pointe réellement un objet de type CMARK, pas le Chuman déclaré par son propre type, il appelle donc intelligemment SaymyName de Cmark.
Delphi utilise des mots clés de remplacement pour illustrer les remplacements de la fonction. La fonction écrasée doit être virtuelle ou dynamique, c'est-à-dire que la fonction doit contenir l'un de ces deux indicateurs lorsqu'il est déclaré, tel que:
Procédure Draw;
Lorsque vous devez remplacer, il vous suffit de le redémarrer avec l'indicateur de remplacement dans la sous-classe.
Procédure Draw;
Syntaxiquement, les déclarations virtuelles et dynamiques sont équivalentes. La différence est que le premier optimise la vitesse de l'implémentation, tandis que le second optimise la taille du code.
Et si la classe de base et la sous-classe contiennent le même nom de fonction et le même paramètre, et que l'indicateur de remplacement n'est pas ajouté à la sous-classe? Ceci est également syntaxiquement correct. Cela signifie que l'implémentation de la fonction de la fonction de la sous-classe masque la mise en œuvre de la classe de base, bien que les deux existent dans la classe dérivée. Revenons ensuite à la situation présentée dans le premier exemple au début de cet article: Quand nous pointerons vers une personne et lui demandons de dire son propre nom, il nous dit qu'il est "une personne", plutôt que de dire la sienne nom.
Il convient de noter que contrairement à la fonction de surcharge et à la fonction de surcharge que nous appelons souvent la surcharge en C ++, dans Delphi, seule la surcharge est ce que nous appelons généralement la surcharge. Bien sûr, lorsque la fonction de la surcharge est la même que les paramètres de fonction de la classe de base, l'implémentation de la classe de base est cachée, tout comme celle mentionnée ci-dessus. Le remplacement signifie rendre la fonction écrasée invisible et en fait écraser, et l'implémentation originale disparaîtra. Pour cette raison, de nombreux articles et même certains livres ont par erreur traduit l'observation par erreur en surcharge, ce qui, je pense, n'est pas approprié.