2013-02-28 1 views
2

J'apprends des choses sur les fonctions virtuelles et les tables virtuelles en C++. Mais, je ne pouvais pas comprendre pourquoi il y a un besoin de liaison dynamique. Ne pas le compilateur ont toutes les informations pour savoir si l'appel de fonction est la dérivée ou la fonction de base, par exemple ici:Polymorphisme C++: Pourquoi la liaison statique est-elle impossible même lorsque le type est évident

class Base1 { 
    public : virtual void foo() 
      { cout << " Base foo \n"; } 
}; 

class Base2 { 
    public : virtual void foo() 
      { cout << " Base2 foo \n"; } 
}; 

class derived : public base1, base 2 { 
    public : virtual void foo() 
     { cout << " derived foo \n"; } 
} 

int main() 
{ 
    derived d; 
    Base2 *p = &d; 
    p->foo();  // why can't the compiler figure out that this 
        // is a function call to the derived function 
        // foo at compile time? 

    return 0; 
} 
+4

Dans ce cas, oui, et certains compilateurs peuvent optimiser l'appel virtuel avec l'analyse de flux simple, mais en général, vous pouvez passer 'p' n'importe où (y compris aux fonctions qui sont dans différentes unités de traduction) et il n'y a pas moyen pour eux de savoir comment 'p' a été initialisé. Même au sein de la même unité de traduction, vous pouvez facilement écrire un programme dans lequel déterminer le type d'exécution de '* p' est halting-problem-complete. –

Répondre

3

pourquoi ne peux pas compilez la figure que c'est un appel de fonction dérivée fonction foo pendant la compilation de l'exécution elle-même?

Il peut. Et certains compilateurs vont convertir cet appel en liaison statique.

Et il existe d'autres scénarios lorsque le compilateur doit utiliser la liaison dynamique.

Quel foo() doit être appelé dans cette fonction?

void function(Base* p) 
{ 
    p->foo(); 
} 

Il ne peut pas être déterminé *. La liaison dynamique doit être utilisée.

* Edit: Basé sur les informations que j'ai données. :)

+4

Eh bien, c'est possible, avec l'analyse de flux interprocedural ... il y a beaucoup de façons de dévirtualiser les appels si vous voulez vraiment :) –