permet de dire que nous avons une classe Le code ci-dessus compilera sur Turbo C (où j'ai testé) et imprimer Je m'attendais à un crash parce que hi code> comme sortie. P>
a code> est
null code>. Plus sur si je fais
Sayhi () code> fonction virtuelle, il est écrit p>
Abnormal temination(Segmentation fault in gcc)
4 Réponses :
en C ++, les méthodes d'une classe ne sont pas stockées dans les instances de cette classe. Ils sont simplement des fonctions «spéciales» qui acceptent de manière transparente le pointeur code> code> en plus des arguments spécifiés par le programmateur. P>
Dans votre cas, la méthode Ne faites aucune erreur, cependant, cela reste un comportement non défini. Votre programme peut choisir d'envoyer des e-mails Nasty à votre liste de contacts lorsque vous l'invoquerez. Dans ce cas particulier, il fait la pire chose et semble fonctionner. P>
Le cas de méthode code> code> a été ajouté depuis que j'ai répondu à la question, mais je ne vais pas affiner ma réponse, car elle est incluse par les réponses des autres. P> Sayhi () code> ne fait référence à aucun des champs de classe, par conséquent, le pointeur code> code> (qui est
null code >) n'est jamais suivi. P>
+1 pour souligner ce comportement non défini qui "fonctionne" est mauvais.
Évidemment, le code a un comportement indéfini, c'est-à-dire que ce que vous obtenez, c'est par hasard. Cela dit, le système n'a pas besoin de savoir sur l'objet lors de la convocation d'une fonction de membre non virtuel: elle peut simplement être appelée en fonction de la signature. En outre, si une fonction membre n'a pas besoin d'accéder à un membre, il n'a pas besoin de vraiment besoin d'un objet du tout et peut simplement courir. C'est ce que vous avez observé lorsque le code imprimait une sortie. Qu'il s'agisse de la manière dont le système est mis en œuvre n'est pas défini, cependant, rien ne dit que cela fonctionne. P>
Lorsque vous appelez un système de type de fonction virtuel, le système commence à regarder un enregistrement d'informations de type associé à l'objet. Lorsque vous appelez une fonction virtuelle sur un pointeur code> null code>, aucune information de ce type n'existe et qui tente d'y accéder, conduit probablement à une sorte de crash. Néanmoins, cela n'a pas besoin, mais cela fait pour la plupart des systèmes. P>
BTW, Main () Code> Toujours STRY> Retours
int code>. P>
Si vous appelez une méthode non virtuelle d'une classe, pour le compilateur, il suffit de savoir quelle classe la fonction appartient à et par la derréférance - bien qu'un pointeur null à une classe pour appeler la méthode, le compilateur obtient cette informations. La méthode Le moment où vous faites cette méthode virtuelle, la situation change. Le compilateur ne sait pas quel code est associé à la méthode au moment de la compilation et doit comprendre cela au moment de l'exécution. Ce qu'il fait, c'est qu'il regarde une table qui contient essentiellement des pointeurs de fonction pour toutes les méthodes virtuelles; Cette table est associée à l'instance de classe, de sorte qu'il regarde le morceau de la mémoire par rapport au pointeur NULL et se bloque donc dans ce cas. P>
comme généralisation, la mise en page d'un objet instancié d'une classe sans classes et fonctions virtuelles est la suivante: dans votre exemple ci-dessus, Le compilateur génère un code qui définit le pointeur implicite code> Ceci code> sur Si vous deviez faire v_ptr code> est un pointeur à La table V - qui contient des adresses de fonctions virtuelles et de données RTTI pour l'objet. Les classes sans fonctions virtuelles n'ont pas de tables V. p>
Classe A code> n'a pas de méthodes virtuelles et donc pas de table V. Cela signifie que la mise en œuvre de
Sayhi () code> à appeler peut être déterminée à l'heure de la compilation et est invariante. p>
A code>, puis passe au début de
Sayhi () Code> . Étant donné que la mise en œuvre n'a pas besoin de contenu de l'objet, le fait qu'il fonctionne lorsque le pointeur est
null code> est une coïncidence heureuse. p>
Sayhi () Code> Virtual, le compilateur ne peut pas déterminer la mise en œuvre à appeler à l'heure du compilateur. Génère donc le code qui lève l'adresse de la fonction dans le Table V-Table et l'appelle. Dans votre exemple où
a code> est
null code>, le compilateur lit le contenu de l'adresse
0 code>, provoquant l'avortement. P> p>
Le fait que la classe A n'a pas de méthodes virtuelles n'est pas pertinente. Ce qui est important, c'est que la fonction particulière soit appelée, Sayhi, n'est pas une fonction virtuelle et n'utilise pas les membres de l'objet de classe. Cette fonction peut donc être appelée (et est) appelée sans utiliser le pointeur sur l'objet de la classe.
Appeler une méthode via un pointeur NULL est un comportement indéfini. Tout peut arriver - il n'est pas nécessaire de s'écraser, mais la norme le permet.
Pas un gars C ++, donc ceci est une suppose, mais: votre code n'a pas besoin d'accéder à la mémoire d'une instance de
A code>.
Sayhi () Code> n'utilise pas le champ
x code>, et ce n'est pas virtuel, il n'est donc pas nécessaire d'accéder à la tablette pour résoudre. Un compilateur C ++ devra réellement insérer un chèque pour voir si
A code> est un pointeur valide pour provoquer une erreur.