Comment le système sait-il quoi utiliser lorsque "Ceci" mot-clé est utilisé? p>
Récemment, on m'a posé cette question dans une interview. N'ayant jamais pensé à cela, j'ai répondu que le système connaîtra le contexte actuel dans lequel le flux de contrôle est et décidera de l'objet d'être utilisé au lieu de cela. L'intervieweur n'a pas regardé heureux et il passa à la question suivante. P>
Quelqu'un peut-il me dire ce que l'intervieweur a peut-être voulu demander et quelle serait la réponse? (Je pense que cela peut interprété de différentes manières et donc à garder cela comme wiki à moins que quelqu'un ne signale pas ..) p>
11 Réponses :
Ce code> est un paramètre masqué dans toutes les méthodes d'un objet et contient une copie du pointeur d'instance. P>
au moment de l'exécution "Ceci" va résoudre le pointeur sur l'objet actuel, "le système" sera donc en mesure d'appeler une méthode respective sur cet objet. P>
"..." Ceci "va résoudre le pointeur à l'objet actuel". Comment ça sait sur l'objet actuel?
Je suppose que la pile de méthodes recevra un paramètre supplémentaire avec une adresse de l'objet dans quel contexte une méthode est exécutée.
in C, ce pointeur est un argument de pointeur invisible à votre classe. P>
Donc, en substance, le premier argument à une méthode de classe est le pointeur de la classe elle-même. Vous y référez-le en utilisant ceci. P>
'Ceci n'est pas un mot clé dans C.
J'aurais répondu "C'est une référence à l'instance de la classe actuelle." P>
DAN P>
Ce n'est pas une réponse à la question du tout.
Le mot clé code> est un pointeur sur l'objet actuel. Tous les fonctions de membre Le pointeur sur l'objet actuel est normalement disponible par le compilateur dans une fonction de membre non statique en utilisant un registre , généralement ecx. Donc, lorsque vous écrivez Vérifiez cet exemple simple: P> ceci code> dans une fonction de membre non statique, le compilateur traduira cet appel dans le chargement de l'adresse d'ECX. P>
004114DE lea ecx,[t]
Comme c'est c #, plus il serait approprié de CIL.
considérer cette classe et ce code qui appelle SetData (): p> lorsque le code ci-dessus est compilé, le compilateur Emet quelque chose équivalent à cela pour la fonction membre: p> et le code d'appel est converti en quelque chose comme ceci: p> Qu'est-ce que cela signifie que lors de la compilation: p> Les fonctions membres sont converties en fonctions simples et globales. P> li>
L'instance de classe auxquelles les fonctions des membres "appartiennent" est simplement transmise en tant que premier argument (ou plutôt que son adresse est passée). P> li>
OL> Donc, en conclusion, ce que vous appelez que ce pointeur de votre code se termine simplement comme le premier argument à la fonction. C'est ainsi que le "système sait" quel objet pour accéder via le "ceci" pointeur. P> L'exemple ci-dessus est de C ++. Si vous oubliez un instant sur le CLR et la jitting et tout cela, que se passe-t-il dans C # est conceptuellement la même chose. P> P>
compilateur shematicaly convertit ce code: dans ce code si "SOMEMETHOD" n'est pas virtuel: p> ou dans ce code Si "Somemethod" est virtuel: p> et partout où vous placez "ce" mot clé premier paramètre est utilisé à la place; p> du compilateur de cours peut optimiser / simplifier en supprimant le premier argument et utiliser un registre de la CPU (normalement ESX) pour stocker l'adresse de l'objet. p> p>
Le compilateur s'occupe de résoudre correctement cette référence lors de la compilation. Si vous voulez en savoir plus sur certaines des techniques qu'ils utilisent pour le faire, ce livre vous dira tout ce que vous devez savoir:
http://fr.wikipedia.org/wiki/compilers:_principles,_techniques, _ et_tools
p>
Ma réponse aurait été "qui se soucie? Ça sait. Si j'ai besoin de savoir plus en détail, je vais google ça." P>
Vous savez évidemment ce que l'effet de l'utilisation de "ceci" serait, ce qui est sûrement la chose importante. Pour 99% des tâches de programmation, j'aurais pensé que le détail de la façon dont il est résolu en interne est une trivia. P>
Cette attitude ne serait probablement pas susceptible de gagner l'approbation de l'intervieweur.
Eh bien, ma réponse si je ne savais pas la réponse réelle serait ce qui sera ci-dessus!
L'opérateur "Cet" pointe sur l'objet actuel. Un exemple où la présence d'un opérateur "Cet" différence sera la différence est la suivante: Notez que "cet" opérateur ne changera pas quelle fonction virtuelle sera appelée si elle est remplacée dans une classe enfant p> si vous exécutez le code suivant p> appellera toujours le myClass2.test () et non Myclass.test () p> Donc, donc l'opérateur "Cet" vous dit simplement que vous accédez à quelque chose déclaré au niveau de la classe. P> P>
Qu'entendez-vous par «que l'opérateur« Cet »ne changera pas quelle fonction virtuelle sera appelée si elle est remplacée dans une classe enfant» ... Qu'entendez-vous par ceci (Pun n'est pas prévu)?
Bien que les réponses qui soulignent que la référence "Cette" référence est essentiellement transmise en tant que magie "paramètre caché" à l'appel est essentiellement correct, l'histoire complète est en fait un peu plus compliquée en C # que d'on pourrait penser au début. coup d'œil. p>
Les types de référence sont simples; L'objet référencé est vérifié pour NULL puis transmis conceptuellement sous forme de paramètre Sans nom, non variables em> appelé "Ceci". L'histoire est compliquée par des types de valeur. p>
N'oubliez pas que les types de valeur sont, par définition, passés par la valeur - c'est-à-dire en effectuant une copie des données. D'où leur nom. Mais des types de valeur mutable clairement mutable - qui sont pure mal et doivent être évités - ne peuvent pas être transmis par la valeur que "Ceci", car si vous appelez un mutateur, le "Ceci" dans la méthode de mutateur serait muté de la copie, non l'original! p>
Par conséquent, dans l'appel de la méthode de type valeur, "Ceci" n'est pas la valeur em> du récepteur, il est un alias à la variable représentant l'emplacement de stockage du récepteur EM >. Nous implémentons cela en passant "Ceci" comme l'adresse gérée em> du récepteur, pas la valeur em> du récepteur. P>
Maintenant, nous pouvons soulever une autre difficulté. Et si la variable stocker la valeur étant mutée est une variable http: //blogs.msdn .Com / Ericlippert / Archive / 2008/05/14 / Mutating-Readonly-Structs.aspx P>
Merci de vous pour vos paroles de sagesse O Tirez-la .... Maintenant, veuillez vous déplacer et mettre en œuvre de nouvelles fonctionnalités de Langue qui soufflera nos esprits collectifs
Merci pour la réponse et un grand lien.
"Le système" voulez-vous dire le compilateur Java? Le compilateur C #?
@Joseph Pouvons-nous le revenir au non-wiki?