2010-08-11 27 views
2

Je suis légèrement confus au sujet du polymorphisme d'exécution. Corrigez-moi si je me trompe, mais à ma connaissance, le polymorphisme d'exécution signifie que les définitions de fonctions seront résolues lors de l'exécution.Que signifie exactement le polymorphisme d'exécution?

Prenez cet exemple:

class a 
{ 
a(); 
~a(); 
void baseclass(); 
} 

class b: class a 
{ 
b(); 
~b(); 
void derivedclass1(); 
} 

class c: class a 
{ 
c(); 
~c(); 
void derivedclass2(); 
} 

méthode d'appel:

b derived1; 
a *baseptr = &derived1; //here base pointer knows that i'm pointing to derived class b. 
baseptr->derivedclass1(); 

Dans la méthode d'appel ci-dessus, la classe de base sait qu'il pointe vers la classe dérivée b.

Alors, d'où vient l'ambiguïté?

Dans quels cas les définitions de fonction seront-elles résolues lors de l'exécution?

+3

Quelle ambiguïté? Le code que vous avez publié ne présente aucun polymorphisme. –

+2

En fait, le code ne compile pas parce que vous ne pouvez pas appeler 'derivedclass1' en utilisant un pointeur sur' a' (sauf si vous lancez explicitement 'b' en premier, bien sûr). – sepp2k

Répondre

5

Il n'existe aucune ambiguïté dans l'exemple fourni.

Si la classe de base a le même nom de fonction que la classe dérivée, et si vous appelez de la manière que vous avez spécifiée, elle appellera la fonction de la classe de base au lieu de la classe dérivée.

Dans ce cas, vous pouvez utiliser le mot-clé virtual pour vous assurer que la fonction est appelée à partir de l'objet pointé. Il est résolu pendant l'exécution.

Here vous pouvez trouver plus d'explications ..

+0

votre lien semble ne fonctionne pas. SVP corrigez-le. Merci. – sree

10

Ce code, lors de l'exécution, appelle la bonne version de f() en fonction du type d'objet (A ou B) réellement créé - pas d'ambiguïté. Le type ne peut pas être connu à la compilation, car il est sélectionné de manière aléatoire au moment de l'exécution.

struct A { 
    virtual ~A() {} 
    virtual void f() {} 
}; 

struct B : public A { 
    virtual void f() {} 
}; 


int main() { 
    A * a = 0; 
    if (rand() % 2) { 
     a = new A; 
    } 
    else { 
     a = new B; 
    } 
    a->f(); // calls correct f() 
    delete a; 
} 
0

Vous devez avoir une méthode commerciale utile déclarée dans la base et dans chaque classe dérivée. Ensuite, vous avez un code tel que

a->someMethod(); 

Maintenant, le pointeur peut pointer vers une instance de l'une des classes dérivées, et donc le type de quel pointe vers doit déterminer quels someMethod() est appelée.

1

Tourner cette

void baseclass(); 

à

virtual void baseclass(); 

Override dans vos classes dérivées b et c. Puis

b *derived1 = new derived1(); 
a *baseptr = derived1; //base pointer pointing to derived class b. 
baseptr->baseclass(); 

invoquera la définition dérivée, exprimant le polymorphisme d'exécution. Et n'oubliez pas de rendre votre destructeur virtuel dans Base. Some basic reading material for polymorphism

1

Runtime signifie que la méthode exacte ne sera connue que lors de l'exécution. Considérez cet exemple:


class BaseClass 
{ 
public: 
    virtual void method() {...}; 
}; 

class DerivedClassA : public BaseClass 
{ 
    virtual void method() {...}; 
}; 

class DerivedClassB : public BaseClass 
{ 
    virtual void method() {...}; 
}; 

void func(BaseClass* a) 
{ 
    a->method(); 
} 

Lorsque vous implémentez votre :: func() vous ne connaissez pas le type d'exemple exactement pointé par BaseClass * a. Il peut s'agir d'une instance DerivedClassA ou DerivedClassB, etc.
Vous devriez réaliser, que le polymorphisme d'exécution nécessite un support spécial de la part du langage (et peut-être une surcharge pour appeler les fonctions "virtuelles"). En C++, vous "demandez" le polymorphisme dynamique en déclarant les méthodes de la classe de base "virtual" et en utilisant l'héritage public.

0

Permet d'avoir une expérience

#include <iostream> 
using namespace std; 
class aBaseClass 
{ 

public: 

    void testFunction(){cout<<"hello base";}///Not declared as virtual!!!! 

}; 
class aDerivedClass:public aBaseClass 
{ 
public: 
    void testFunction(){cout<<"hello derived one";} 
}; 

class anotherDerivedClass:public aDerivedClass 
{ 
public: 
    void testFunction(){cout<<"hello derived two";} 

}; 
int main() 
{ 
    aBaseClass *aBaseClassPointer; 
    aBaseClassPointer=new aDerivedClass; 
    aBaseClassPointer->testFunction(); 
} 

Le code ci-dessus ne supporte pas polymorphisme moment de l'exécution. Laisse courir et l'analyser. La sortie est

hello base 

il suffit de changer la ligne void testFunction(){cout<<"hello base";}-virtual void testFunction(){cout<<"hello base";} en aBaseClass. Courez et analysez-le. Nous voyons que le polymorphisme d'exécution est atteint. L'appel de la fonction appropriée est déterminé au moment de l'exécution.

Modifier à nouveau la ligne aBaseClassPointer=new aDerivedClass à aBaseClassPointer=new anotherDerivedClass dans la fonction principale et voir la sortie. Ainsi, l'appel de fonction approprié est déterminé au moment de l'exécution (lorsque le programme est en cours d'exécution).