2010-09-17 3 views
0

Supposons que j'ai deux classés Base et Derived, i.e. .:Boucle infinie en utilisant static_cast sur ce pointeur

#include <iostream> 

    class Base { 
    public: 
     Base() 
      : m_name("Base") 
     { 
     } 

     virtual ~Base() 
     { 
     } 

     virtual void method (std::ostream & out) const 
     { 
      out << m_name << std::endl; 
     } 

    protected: 
     Base (std::string name) 
      : m_name(name) 
     { 
     } 

    private: 
     std::string m_name; 
    }; 

    class Derived : public Base { 
    public: 
     Derived() 
      : Base("Derived") 
     { 
     } 

     virtual ~Derived() 
     { 
     } 

     virtual void method (std::ostream & out) const 
     { 
      static_cast<const Base * const>(this)->method(out); 
     } 
    }; 

Si j'appelle Derived::method(), je reçois une boucle infinie.

int main() 
{ 
Derived d; 
d.method(std::cout); 

return 0; 
} 

Bien sûr. Je peux changer static_cast<const Base * const>(this)->method(out); à Base::method(out) et tout ira bien, mais je suis intéressé par la raison derrière ce comportement. Les deux ne devraient-ils pas avoir le même comportement?

Alors quelqu'un peut-il expliquer ce qui se passe ici? D'un côté, j'ai compilé le code avec g++ -Wall -Wextra -O2 -g foo.cpp -o foo. Y a-t-il une chance d'obtenir un avertissement pour ce type de code?

Répondre

6

Probablement vous avez déjà deviné: static_cast<const Base * const>(this)->method(out); est un appel virtuel, ce qui signifie que la fonction est appelée à l'intérieur de lui-même. Dans ce cas, cela entraînerait un débordement de pile. Base::method(out) n'est pas un appel virtuel.

4

Vous avez déclaré la fonction membre comme virtuelle. En termes simples, cela signifie que l'implémentation de la classe dérivée sera appelée lorsque vous accéderez à l'objet via un pointeur vers la classe de base.

Questions connexes