herencia : funcion virtual no se ejecuta..

Iniciado por digimikeh, 15 Noviembre 2020, 02:03 AM

0 Miembros y 1 Visitante están viendo este tema.

digimikeh

Hola amigos..
Que pasa en este codigo que la funcion virtual do_xy() en x no se está ejecutando?

Código (cpp) [Seleccionar]

#include <iostream>

struct x{ 
  x(){}
  ~x(){}
 
protected:
  virtual void do_xy(){
      cout << "from x " << endl;     //esto no se ejecuta
  } 
};

struct y : public x{
  y(){}
  ~y(){}
 
public:
  void do_xy() override{
      cout << "from y " << endl;     //esto se ejecuta
  }   
};

int main(){
    y _y;
    _y.do_xy();
   
    cin.get();
    return 0;
}


Saludos.. gracias.
Dungeons & dragons;
dragons.Attack();

K-YreX

Claro.

En este caso en concreto no se ejecuta por 2 motivos:
  • La variable creada es del tipo de la struct derivada. Entonces se llama a la función definida ahí.
  • Una función virtual se define así para eso, para poder llamar a la función más adecuada en tiempo de ejecución

    Si creas las funciones sin usar virtual, se decide en tiempo de compilación a qué función llamar:
    Código (cpp) [Seleccionar]

    struct Base {
      void show(){
        cout << "Base" << endl;
      }
    };

    struct Derived : Base {
      void show(){
        cout << "Derived" << endl;
      }
    };

    int main(){
      Base b;
      b.show(); // b es de tipo Base, se muestra: Base
      Derived d;
      d.show(); // d es de tipo Derived, se muestra: Derived
      // LA DIFERENCIA ESTA AQUI:
      Base *p = &b;
      p->show(); // El puntero es de tipo Base, se muestra: Base
      p = &d;
      p->show(); // El puntero sigue siendo de tipo Base, se muestra: Base
    }


    En cambio, si definimos la función como virtual:
    Código (cpp) [Seleccionar]

    struct Base {
      virtual void show(){
        cout << "Base" << endl;
      }
    };

    struct Derived : Base {
      void show(){
        cout << "Derived" << endl;
      }
    };

    int main(){
      Base b;
      b.show(); // b es de tipo Base, se muestra: Base
      Derived d;
      d.show(); // d es de tipo Derived, se muestra: Derived
      // LA DIFERENCIA ESTA AQUI:
      Base *p = &b;
      p->show(); // La variable a la que apunta es de tipo base, se muestra: Base
      p = &d;
      p->show(); // La variable a la que apunta es de tipo derived, se muestra: Derived
    }


    No sé si se ve bien. La diferencia es que si la función es virtual, en tiempo de ejecución se comprueba de qué tipo es la variable a la que está apuntando un puntero y se utiliza su función correspondiente. Si no se usa virtual, el compilador coge el tipo del puntero y llama a la función de su clase sin importarle de qué clase es la variable a la que apunta.
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

digimikeh

Entiendo, gracias..

La idea mia es que se ejecute en cadena.. como un ensamble, es decir, la linea

Código (cpp) [Seleccionar]

_y.do_xy();


deberia ejecutar:
from x
from y


por esta razon utilice el keyword "override"...
Dungeons & dragons;
dragons.Attack();

K-YreX

Para llamar a la función de la clase base tienes que usar ::.
Código (cpp) [Seleccionar]

struct Base {
  virtual void show(){
    cout << "Base" << endl;
  }
};

struct Derived : Base {
  void show(){
    Base::show();
    cout << "Derived" << endl;
  }
};

int main(){
  Derived d;
  Base *p = &d;
  p->show();
}


SALIDA:

Base
Derived
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

digimikeh

Dungeons & dragons;
dragons.Attack();