2017-08-08 3 views
1

J'ai trois classes suivantes:Polymorphisme en C++ (Comportement inattendu)

class A 
{ 
private: 
    std::string device; 
public: 
    std::string getDeviceType() { return device; }; 
    void setDeviceType(std::string device) { device = device; }; 
    virtual void doSomething() = 0; 
    virtual void doSomething2() = 0; 
}; 

class B: public A 
{ 
    private: 
    public: 
     B(){ ; }; 
     virtual ~B(){ ; }; 
     void doSomething() { std::cout << "I am usual B" << std::endl; }; 
     void virtual doSomething2() { std::cout << "I am usual B" << std::endl; }; 
}; 

class C : public B 
{ 
private: 
public: 
    C(){ ; }; 
    ~C(){ ; }; 
    void doSomething() { std::cout << "I am C" << std::endl; }; 
    void doSomething2() { std::cout << "I am C" << std::endl; }; 
}; 

principales:

B *myHandler = new C(); 
myHandler->doSomething(); 
myHandler->doSomething2(); 

mais la production est pas comme prévu, mon résultat attendu a été I am usual B puis I am C, parce que doSomething() est un membre non virtuel de la classe B. Mais la sortie réelle était I am C puis I am C. Est-ce que tu sais pourquoi?

+0

[OT] '{device = dispositif; } 'devrait être' {this-> device = device; } ', ou utilisez des noms différents. – Jarod42

+3

Les méthodes surchargées restent virtuelles; Comme 'A :: doSomething' est,' B :: doSomething' et 'C :: doSomething' le sont aussi, indépendamment de la répétition du mot-clé' virtual' dans leur déclaration. – YSC

Répondre

4

La raison est que doSomething est marqué comme virtuel dans la classe A. Il reste donc virtuel dans les classes B et C car ils héritent de la classe A.

Comme cette fonction est virtuelle, il est appelé en fonction du type réel de l'objet, qui est C dans votre cas, et vous obtenez la sortie: I am C.

0

Une fois marqué virtuel, il reste virtuel dans toutes les classes dérivées.

En C, vous annulez à la fois doSomething() et doSomething2(). Vous instanciez C, donc les méthodes de C sont appelées dans les deux cas.

Si vous omettez le remplacement dans C de doSomething(), la sortie sera comme vous l'attendiez.

KR,

Melle