Il y a beaucoup de raisons pourquoi les compilateurs ne peuvent pas en général de remplacer le moteur d'exécution de la décision avec les appels statiques, surtout parce qu'il comporte de l'information non disponible au moment de la compilation, par exemple, de la configuration ou de la saisie de l'utilisateur. A côté de cela, je tiens à souligner deux autres raisons pour lesquelles ce n'est pas possible en général.
Tout d'abord, la compilation C++ modèle est basé sur des unités de compilation. Quand une unité est compilé, le compilateur ne connaît que ce qui est défini dans le fichier source(s) en cours d'élaboration. Considérons une unité de compilation avec une classe de base et une fonction prise d'une référence à la classe de base:
struct Base {
virtual void polymorphic() = 0;
};
void foo(Base& b) {b.polymorphic();}
Lorsqu'il est compilé séparément, le compilateur n'a pas de connaissances sur les types qui implémentent Base
et donc ne peut pas supprimer la dynamique de l'expédition. Il a également pas quelque chose que nous voulons parce que nous voulons pouvoir étendre le programme avec de nouvelles fonctionnalités par la mise en œuvre de l'interface. Il peut être possible de le faire au moment de la liaison, mais seulement sous l'hypothèse que le programme est entièrement terminée. Bibliothèques dynamiques peut casser cette hypothèse, et comme on peut le voir dans la suite, il y aura toujours des cas où il n'est pas possible à tous.
Une raison plus fondamentale vient de la Compilation de la théorie. Même avec l'information complète, il n'est pas possible de définir un algorithme qui calcule si une ligne dans un programme sera atteint ou non. Si vous pouviez vous pourriez résoudre le Problème de l'Arrêt: pour un programme d' P
,- je créer un nouveau programme P'
par l'ajout d'une ligne supplémentaire à la fin de l' P
. L'algorithme serait maintenant en mesure de décider si cette ligne est atteint, ce qui résout le Problème de l'Arrêt.
Être incapable de décider, en général, signifie que les compilateurs ne peut pas décider quelle valeur est affectée à des variables, en général, par exemple
bool someFunction( /* arbitrary parameters */ ) {
// ...
}
// ...
Base* b = nullptr;
if (someFunction( ... ))
b = new Derived1();
else
b = new Derived2();
b->polymorphicFunction();
Même lorsque tous les paramètres sont connus au moment de la compilation, il n'est pas possible de prouver en général qui chemin à travers le programme et qui de type statique b
. Des Approximations peuvent être et sont faits par l'optimisation des compilateurs, mais il y a toujours des cas où il ne fonctionne pas.
Ceci dit, les compilateurs C++ essayez très difficile de l'enlever répartition dynamique, car elle ouvre de nombreux autres l'optimisation des chances principalement d'être en mesure de l'inclure et de propager la connaissance à travers le code. Si vous êtes intéressant, vous pouvez trouver une intéressante graves de messages de blog pour le CCG devirtualization mise en œuvre.