Question

class A {
       public :
       void printSometext() {
       std::cout << "printing A" << std::endl;
       }
    };
class B {
       public : 
       void printSometext() {
       std::cout << "printing B" << std::endl;
       }
    };

int main() {
   A* a = new A();
   a->printSometext();
   return 0;
}

Comment l'objet de C conserve des informations sur ses fonctions membres. Permet de considérer au-dessus du code. Quand j'appelle printSometext sur l'objet « a » comment savoir quelle fonction d'appel et comment il trouve la bonne méthode. Lors de l'impression de la taille de l'objet qu'elle imprime la taille de sommation de sa variable membre (+) de allignments. Alors, s'il vous plaît fournir des informations internes comment l'appel de fonction membre a lieu.

Merci, Deimus

Était-ce utile?

La solution

Eh bien, c'est une question intéressante, mais je vais essayer de répondre à cette façon très méthodique !!!

Disons que le compilateur doit résoudre un appel comme celui-ci: *

a-> someFunc ();

*.

Maintenant, compilateur passer en suivant les étapes méthodiquement.

1.) Tout d'abord, le compilateur connaît le type déclaré d'une variable, il vérifiera si le type déclaré de l'objet a ( lets call this, class A for time being ), une méthode avec le nom someFunc () et que il doit être public. Cette méthode pourrait être soit déclarée en class A, ou il pourrait être une méthode dérivée d'un de la classe de base (es) de la classe A, mais il n'a pas d'importance au compilateur et il contrôle simplement pour son existence avec elle spécificateur de l'accès étant public .

  • Inutile de dire que toute erreur dans cette étape invitera une erreur de compilation.

2.) En second lieu, une fois que la méthode est validée pour être une partie de la classe A, le compilateur doit résoudre l'appel à la bonne méthode, car de nombreuses méthodes pourraient être là avec le même nom (grâce à une surcharge de fonction). Ce processus de résolution de bonne méthode est appelée overloading resolution. Compilateur y parvient en faisant correspondre les signatures de la méthode appelée avec toutes les méthodes surchargées qui font partie de la classe. Alors, tous les someFunc() s que le someFunc () correcte (correspondant à la signature avec méthode appelée) sera trouvée et un examen plus approfondi.

3.) Maintenant vient la partie difficile, il peut très bien arriver que someFunc () peut-être surchargée dans l'une des sous-classes de la classe A (lets call this class AA and needless to say it is some subclass of A), et qu'une variable (déclarée comme étant de type A) peut effectivement faire référence à un objet de classe AA, (ce qui est admissible en C ++ afin de permettre le polymorphisme). Maintenant, si la méthode someFunc () est déclaré comme étant de type virtual, dans la classe de base (par exemple de classe A) et someFunc () a été remplacée par les sous-classe (s) de A (soit en AA ou des classes entre A et AA), la version correcte de someFunc () doivent être trouvées par le compilateur.

  • Maintenant, imaginez que vous êtes le compilateur et vous avez cette tâche de trouver si le AA de classe a cette méthode. De toute évidence, la classe AA aura cette méthode depuis, il est une sous-classe A et l'accès du public d'une classe A a déjà été validée à l'étape 1 par le compilateur !!! . Mais Sinon, comme mentionné au paragraphe précédent, someFunc () peut être remplacée par classe AA (ou toute autre classe entre A et AA), qui est doit rattraper ce compilateur. Par conséquent, vous (puisque, your'e jouant le compilateur) pourrait faire une vérification systématique pour trouver le plus en bas (le plus bas dans l'arbre d'héritage) méthode surchargée someFunc () à partir de la classe A et se terminant à la classe AA. Dans cette recherche, vous aurez l'air pour les signatures mêmes de la méthode a été validée que dans la résolution de surcharge. Cette méthode sera la méthode qui sera invoquée.

  • Maintenant, vous demandez peut-être, « Que diable », est cette recherche fait à chaque fois? ... Eh bien pas vraiment. Le compilateur connaît la surcharge de trouver ce à chaque fois, et en tant que telle, maintient une structure de données appelée Virtual Table pour chaque type de classe. Penser à table virtuelle, que la cartographie de signatures de méthode (qui sont accessibles au public) aux pointeurs de fonction. Cette table virtuelle est fait par le compilateur lors de la compilation et est maintenue en mémoire pendant l'exécution du programme. Dans notre exemple, la classe A et la classe AA ont tous deux leurs propres tables virtuelles. Et quand le compilateur doit être trouver someFunc () dans la classe AA (depuis l'objet réel pointé par une variable est de type AA), il suffit de trouver le pointeur de fonction à travers la table virtuelle de classe AA. Ceci est aussi simple a hachage dans la table et est une opération de constante de temps.

Cordialement

avid

Autres conseils

Vous avez les bases de la mauvaise programmation de C. a ne sait pas printSomeText au moment de l'exécution, il est le compilateur et éditeur de liens qui se traduit par le code ci-dessus au code binaire qui exécute ces tâches. Lors de l'exécution, il y a juste un tas d'instructions.

Ajout à la réponse de l'Asha (+1):

Si vous voulez vraiment comprendre comment les choses fonctionne en interne, je vous suggère d'apprendre et d'explorer l'ensemble du code machine généré. Voilà ce que je l'ai fait.

Le compilateur connaît les types des variables. Lorsque vous utilisez la . ou l'opérateur ->, il recherche le symbole à gauche dans la contexte du type de classe de l'argument de la main droite. Ainsi, dans votre exemple, il ne trouve que :: printSomeText.

- James Kanze

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top