‫Entonces, en esta lección, hablaremos sobre el método virtual en C++.
‫Lo hemos visto antes, lo hemos usado, pero ¿lo hemos entendido completamente?
‫Dejanos ver.
‫Entonces, la idea de un método virtual es que nos permite anular funciones en una clase base.
‫Hemos visto esto con cosas como comenzar, jugar y tomar Unreal.
‫Pero profundicemos en esto y entendamos por qué están marcados como virtuales.
‫Nos permite cambiar la funcionalidad en esa clase base y hace algo llamado Dynamic Dispatch, de lo que hablaremos en
‫un segundo para entender qué significa realmente y por qué los métodos virtuales no son
‫la funcionalidad predeterminada en C++. como lo están en muchos otros idiomas, como C Sharp.
‫Así que echemos un vistazo a esto.
‫Voy a hacer esto en el sitio web CPP dot S-H para que no estemos en Unreal aquí en absoluto.
‫Solo estamos analizando la funcionalidad de C++ sin formato para que pueda comprender esta característica del lenguaje y
‫cómo funciona.
‫Ahora, lo primero que voy a hacer aquí es continuar y borrar el método principal.
‫Y en nuestro caso de uso vamos a pensar en una clase para armas de fuego, dado que este es un caso de uso muy común
‫para los juegos.
‫Así que echemos un vistazo a una clase, enfriémosla de manera bastante directa y luego haremos que el
‫cuerpo de esta clase sea público y un método de disparo vacío.
‫Y voy a seguir adelante y declarar el cuerpo de este método de disparo justo aquí en línea para mantener las
‫cosas súper simples.
‫Por cierto, puedes hacer esto si no lo has visto antes.
‫Pero, en términos generales, queremos hacer las cosas en un archivo C++ separado para mantener las cosas separadas, para que los tiempos
‫de compilación sean más rápidos, etc.
‫Pero aquí, donde es solo un ejemplo de juguete, está bien.
‫Así que vamos a hacer un SD para ver.
‫Entonces, usando C ++ como material de cadena de salida y vamos a explotar.
‫Básicamente cuando llamamos a este método y luego vamos a la línea final.
‫Y ese es el cuerpo de nuestro método chute.
‫Y podemos rematar la clase donde están las llaves y el punto y coma.
‫Así que sigamos adelante y usemos esta clase.
‫Voy a crear una variable my gun en main y voy a llamar a mi gun dot shoot y vamos a ver si
‫todo funciona aquí como debería.
‫Presiona el botón ejecutar y bang.
‫Está llamando al método como esperábamos.
‫Ahora, ¿qué sucede si quiero extender mi arma y tal vez hacer un rifle o una pistola que se llame pistola?
‫Así que la pistola de clase es heredada de una pistola, que funcionaría así.
‫Y si no habías visto esto antes porque probablemente no lo hayas escrito necesariamente
‫antes, haces una herencia pública de armas para que otras clases puedan ver que heredas de armas.
‫Y luego lo hacemos en la sección pública, tal vez queremos crear nuestro propio método de disparo para la pistola que
‫anule esta funcionalidad.
‫Y en lugar de imprimir bang al final aquí, queremos imprimir píldora porque es un arma más pequeña, hace un sonido
‫más pequeño y ese es nuestro método de disparo allí.
‫Y terminemos la clase allí.
‫Y lo que queremos hacer es crearnos una pistola.
‫Así que dispara mi pistola en el método principal aquí.
‫Y debido a que estos solo existen aquí, justo en el método principal, no estamos usando punteros para ellos.
‫Es por eso que estamos usando el operador punto aquí en lugar de la flecha.
‫Así que mi punto de pistola dispara.
‫Veamos qué hace eso.
‫Espero que imprima ppu, lo cual hace.
‫Frio.
‫Bien, eliminemos nuestros métodos que están llamando.
‫Dispare directamente sobre estos y veamos cómo se comportarían las cosas con un puntero.
‫Así que voy a crear un puntero de pistola llamado pistola.
‫Pedro
‫Y en la siguiente línea podría hacerlo en la misma línea, pero por simplicidad, lo haré en la siguiente
‫línea.
‫Voy a configurar el puntero de la pistola para que apunte a la dirección de la dirección del operador, la dirección de
‫la variable de mi pistola.
‫Y luego, debido a que es un puntero, necesitamos usar el operador de flecha para llamar al método de disparo.
‫Así que voy a llamar a disparar con mi arma.
‫Hagamos clic en Ejecutar y obtendremos el resultado allí.
‫Frio.
‫Ahora, ¿qué pasa si hago lo mismo?
‫Pero en lugar de apuntar el arma para que apunte a mi arma, la configuré para que apunte a mi pistola.
‫Sigamos adelante y presione ejecutar ahora.
‫Bueno.
‫Ese es un comportamiento interesante allí.
‫Lo que sucede aquí es llamar a este primer método en ambos casos.
‫Entonces, ¿por qué no se ha llamado a este segundo método de disparo?
‫Tenemos una pistola aquí como puntero.
‫Bueno, lo que sucede si no tiene un método virtual es que, de manera predeterminada, C++ usará el tipo de su
‫puntero, que es un puntero de pistola.
‫Recuerde, usará ese tipo para encontrar el método para llamar.
‫Entonces irá y llamará a este método de disparo en la parte superior en lugar del método anulado en pistola.
‫Para que pueda llamar al método anulado en pistola, tendría que llamar.
‫Tendría que tener un puntero de tipo pistola.
‫Ahora que está bien.
‫Y puedes ver por qué hacen esto.
‫Es por eficiencia.
‫C++ tiene que ver con la eficiencia.
‫Si algo va a costar más cuando se compila, cuando se ejecuta, entonces C ++ no lo hará de forma predeterminada a menos
‫que se lo solicite.
‫Así que es muy fácil para C++ buscar y decir, Bueno, esto es un puntero de pistola, así que llamaré a este método
‫de puntero de pistola.
‫Y aquí es donde entra Dynamic Dispatch.
‫Este término elegante básicamente significa que no queremos que haga eso.
‫Lo que queremos que haga es decir, espera un segundo, ¿qué está realmente almacenado en ese puntero de pistola?
‫¿Cuál es el tipo real allí?
‫Y el tipo real que nos damos cuenta es que es un tipo pistola.
‫Entonces, debemos preguntarnos, ¿hay algún método para ese tipo que se anule?
‫Y sí, lo hay.
‫Entonces, ¿cómo le damos a C++ el permiso para ser un poco menos eficiente y nos da la capacidad de
‫anular sin tener que cambiar ese tipo de puntero, lo que no siempre es necesariamente posible?
‫De hecho, en muchos casos no es posible, como es el caso cuando tienes tu propia clase activa
‫personalizada.
‫Unreal no tiene el puntero configurado para apuntar a su clase en particular, lo que requeriría que cambien todo
‫el motor cada vez que introduce una nueva clase.
‫No, eso simplemente no es posible.
‫Tienen un puntero a algo de tipo actuar para protagonizar.
‫Entonces, cuando llamen a Begin Play, usted quería llamar a su método Begin Play.
‫Así que tiene que ser virtual.
‫Y esa es la clave aquí.
‫Si ponemos virtual delante del método en la clase principal, esto ahora le indica a C++ que espera un segundo, si estoy llamando
‫a disparar en un puntero de tipo puntero de pistola, necesito verificar que esto no sea así, por ejemplo , una
‫pistola y que este método de disparo ha sido anulado.
‫Entonces, si seguimos adelante y presionamos ejecutar ahora, pueden ver que obtenemos bang y luego pue.
‫Así que está funcionando como esperábamos con despacho dinámico.
‫Y ese es el término para esta cosa en la que básicamente solo queremos decir verificar qué tipo de tipo se está manteniendo
‫realmente en el puntero y llamar al método relevante.
‫Ahora, hay un poco más de sintaxis que a menudo nos verá usar, y esa es la palabra
‫clave override.
‫Y lo coloca después de un método que está tratando de anular como virtual.
‫Y, básicamente, la palabra clave anular no es estrictamente necesaria, ni tampoco lo es volver a poner virtual contra algo en
‫la clase secundaria de un arma.
‫Así que no tienes que poner virtual, pero no está de más hacerlo.
‫Pero la anulación es particularmente útil porque nos permite asegurarnos de que tenemos el nombre
‫correcto.
‫Entonces, si presiono ejecutar, todo funciona como antes cuando tengo la anulación.
‫Pero digamos que me equivoqué por error en el nombre de este método, así que no hago la anulación.
‫Y lo había llamado un tirador de notas, por ejemplo.
‫Copié mal el nombre.
‫Lo escribí en lugar de copiarlo.
‫Si presiono correr ahora, entonces verás, tenemos el mismo error nuevamente porque estamos tratando de enfriarnos para disparar.
‫Por error lo anulamos incorrectamente.
‫Va bang, bang.
‫Entonces, la forma en que podría evitar esto es diciendo: Bueno, estoy tratando de anular algo.
‫Así que puse mi palabra clave de anulación aquí, y si trato de compilarla ahora, puede ver que está diciendo que
‫el tirador está marcado como anulado, pero no hay ningún método, ningún método virtual para anular, en cuyo caso
‫puedo ir , Oh sí, lo he escrito mal.
‫Así que voy a seguir adelante y corregir mi código y volver a disparar.
‫Y ahora funciona como pretendía.
‫Entonces, es solo un poco de seguridad adicional al poner esa anulación allí e instantáneamente esto.
‫También nos protegería contra el caso de que lo que estamos tratando de anular no sea virtual.
‫Si trato de hacer eso, puede ver que dice que está marcado como anulado, pero no
‫lo anula porque esa clase principal no tiene una función virtual para disparar.
‫Entonces, espero que esto le brinde una descripción general de cómo C ++ usa e implementa funciones virtuales y por
‫qué tenemos que ser tan explícitos al respecto.
‫Ahora, pensemos en algunos casos de uso más para funciones virtuales en general.
‫Ya hemos visto algunos del motor.
‫¿Dónde has visto virtual antes?
‫¿Dónde te imaginas usándolo?
‫Acabamos de ver un ejemplo de caso de uso en el que puede tener un arma y diferentes anulaciones de eso
‫que implementan disparar de diferentes maneras.
‫¿De qué otra manera podrías imaginar usar funciones virtuales para anular la funcionalidad en las clases principales?
‫Cuando haya pensado en una respuesta a esas dos preguntas, vaya y siga el enlace a
‫las discusiones en esta lección y publique su respuesta.
‫Muestran los casos de uso y los lugares en los que los ha usado antes y ven lo que se les ha ocurrido a otras
‫personas.
‫Tal vez eso lo ayude a solidificar su comprensión de los métodos virtuales.
‫Eso es todo por esta conferencia.
‫Nos vemos en el próximo donde estaremos usando métodos virtuales en la ira.