﻿1
00:00:04,440 --> 00:00:09,690
‫Entonces, en esta lección, hablaremos sobre el método virtual en C++.

2
00:00:09,690 --> 00:00:13,110
‫Lo hemos visto antes, lo hemos usado, pero ¿lo hemos entendido completamente?

3
00:00:13,110 --> 00:00:13,860
‫Dejanos ver.

4
00:00:14,220 --> 00:00:20,400
‫Entonces, la idea de un método virtual es que nos permite anular funciones en una clase base.

5
00:00:20,400 --> 00:00:24,690
‫Hemos visto esto con cosas como comenzar, jugar y tomar Unreal.

6
00:00:25,020 --> 00:00:29,640
‫Pero profundicemos en esto y entendamos por qué están marcados como virtuales.

7
00:00:30,030 --> 00:00:38,130
‫Nos permite cambiar la funcionalidad en esa clase base y hace algo llamado Dynamic Dispatch, de lo que hablaremos en

8
00:00:38,430 --> 00:00:44,520
‫un segundo para entender qué significa realmente y por qué los métodos virtuales no son

9
00:00:44,520 --> 00:00:50,610
‫la funcionalidad predeterminada en C++. como lo están en muchos otros idiomas, como C Sharp.

10
00:00:50,910 --> 00:00:52,050
‫Así que echemos un vistazo a esto.

11
00:00:52,500 --> 00:00:59,850
‫Voy a hacer esto en el sitio web CPP dot S-H para que no estemos en Unreal aquí en absoluto.

12
00:00:59,850 --> 00:01:05,130
‫Solo estamos analizando la funcionalidad de C++ sin formato para que pueda comprender esta característica del lenguaje y

13
00:01:05,130 --> 00:01:05,820
‫cómo funciona.

14
00:01:06,300 --> 00:01:10,440
‫Ahora, lo primero que voy a hacer aquí es continuar y borrar el método principal.

15
00:01:10,770 --> 00:01:18,390
‫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

16
00:01:18,390 --> 00:01:19,380
‫para los juegos.

17
00:01:19,830 --> 00:01:26,700
‫Así que echemos un vistazo a una clase, enfriémosla de manera bastante directa y luego haremos que el

18
00:01:26,700 --> 00:01:31,560
‫cuerpo de esta clase sea público y un método de disparo vacío.

19
00:01:32,550 --> 00:01:38,400
‫Y voy a seguir adelante y declarar el cuerpo de este método de disparo justo aquí en línea para mantener las

20
00:01:38,400 --> 00:01:39,290
‫cosas súper simples.

21
00:01:39,300 --> 00:01:41,310
‫Por cierto, puedes hacer esto si no lo has visto antes.

22
00:01:41,520 --> 00:01:47,820
‫Pero, en términos generales, queremos hacer las cosas en un archivo C++ separado para mantener las cosas separadas, para que los tiempos

23
00:01:47,820 --> 00:01:49,560
‫de compilación sean más rápidos, etc.

24
00:01:49,860 --> 00:01:52,140
‫Pero aquí, donde es solo un ejemplo de juguete, está bien.

25
00:01:52,650 --> 00:01:55,260
‫Así que vamos a hacer un SD para ver.

26
00:01:55,260 --> 00:01:59,730
‫Entonces, usando C ++ como material de cadena de salida y vamos a explotar.

27
00:02:00,360 --> 00:02:04,710
‫Básicamente cuando llamamos a este método y luego vamos a la línea final.

28
00:02:05,630 --> 00:02:07,820
‫Y ese es el cuerpo de nuestro método chute.

29
00:02:07,820 --> 00:02:11,510
‫Y podemos rematar la clase donde están las llaves y el punto y coma.

30
00:02:12,050 --> 00:02:14,680
‫Así que sigamos adelante y usemos esta clase.

31
00:02:14,690 --> 00:02:23,420
‫Voy a crear una variable my gun en main y voy a llamar a mi gun dot shoot y vamos a ver si

32
00:02:23,420 --> 00:02:25,670
‫todo funciona aquí como debería.

33
00:02:26,000 --> 00:02:27,830
‫Presiona el botón ejecutar y bang.

34
00:02:28,210 --> 00:02:30,260
‫Está llamando al método como esperábamos.

35
00:02:31,040 --> 00:02:40,220
‫Ahora, ¿qué sucede si quiero extender mi arma y tal vez hacer un rifle o una pistola que se llame pistola?

36
00:02:40,580 --> 00:02:46,970
‫Así que la pistola de clase es heredada de una pistola, que funcionaría así.

37
00:02:47,180 --> 00:02:51,470
‫Y si no habías visto esto antes porque probablemente no lo hayas escrito necesariamente

38
00:02:51,470 --> 00:02:56,090
‫antes, haces una herencia pública de armas para que otras clases puedan ver que heredas de armas.

39
00:02:56,720 --> 00:03:04,220
‫Y luego lo hacemos en la sección pública, tal vez queremos crear nuestro propio método de disparo para la pistola que

40
00:03:04,220 --> 00:03:05,510
‫anule esta funcionalidad.

41
00:03:05,510 --> 00:03:13,190
‫Y en lugar de imprimir bang al final aquí, queremos imprimir píldora porque es un arma más pequeña, hace un sonido

42
00:03:13,190 --> 00:03:17,270
‫más pequeño y ese es nuestro método de disparo allí.

43
00:03:17,450 --> 00:03:19,910
‫Y terminemos la clase allí.

44
00:03:20,510 --> 00:03:23,290
‫Y lo que queremos hacer es crearnos una pistola.

45
00:03:23,300 --> 00:03:27,740
‫Así que dispara mi pistola en el método principal aquí.

46
00:03:28,640 --> 00:03:33,980
‫Y debido a que estos solo existen aquí, justo en el método principal, no estamos usando punteros para ellos.

47
00:03:33,980 --> 00:03:38,240
‫Es por eso que estamos usando el operador punto aquí en lugar de la flecha.

48
00:03:38,840 --> 00:03:42,020
‫Así que mi punto de pistola dispara.

49
00:03:42,200 --> 00:03:43,190
‫Veamos qué hace eso.

50
00:03:43,670 --> 00:03:47,030
‫Espero que imprima ppu, lo cual hace.

51
00:03:47,320 --> 00:03:47,690
‫Frio.

52
00:03:48,230 --> 00:03:51,470
‫Bien, eliminemos nuestros métodos que están llamando.

53
00:03:51,470 --> 00:03:56,810
‫Dispare directamente sobre estos y veamos cómo se comportarían las cosas con un puntero.

54
00:03:57,410 --> 00:04:01,580
‫Así que voy a crear un puntero de pistola llamado pistola.

55
00:04:02,640 --> 00:04:03,420
‫Pedro

56
00:04:04,600 --> 00:04:08,440
‫Y en la siguiente línea podría hacerlo en la misma línea, pero por simplicidad, lo haré en la siguiente

57
00:04:08,440 --> 00:04:08,860
‫línea.

58
00:04:08,860 --> 00:04:16,030
‫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

59
00:04:16,030 --> 00:04:18,070
‫la variable de mi pistola.

60
00:04:18,670 --> 00:04:23,710
‫Y luego, debido a que es un puntero, necesitamos usar el operador de flecha para llamar al método de disparo.

61
00:04:23,830 --> 00:04:26,410
‫Así que voy a llamar a disparar con mi arma.

62
00:04:26,830 --> 00:04:30,310
‫Hagamos clic en Ejecutar y obtendremos el resultado allí.

63
00:04:30,370 --> 00:04:30,850
‫Frio.

64
00:04:31,330 --> 00:04:34,420
‫Ahora, ¿qué pasa si hago lo mismo?

65
00:04:34,420 --> 00:04:40,570
‫Pero en lugar de apuntar el arma para que apunte a mi arma, la configuré para que apunte a mi pistola.

66
00:04:40,960 --> 00:04:42,280
‫Sigamos adelante y presione ejecutar ahora.

67
00:04:42,850 --> 00:04:43,200
‫Bueno.

68
00:04:43,210 --> 00:04:44,950
‫Ese es un comportamiento interesante allí.

69
00:04:45,340 --> 00:04:51,610
‫Lo que sucede aquí es llamar a este primer método en ambos casos.

70
00:04:52,000 --> 00:04:55,450
‫Entonces, ¿por qué no se ha llamado a este segundo método de disparo?

71
00:04:55,450 --> 00:04:57,790
‫Tenemos una pistola aquí como puntero.

72
00:04:58,390 --> 00:05:05,440
‫Bueno, lo que sucede si no tiene un método virtual es que, de manera predeterminada, C++ usará el tipo de su

73
00:05:05,440 --> 00:05:07,900
‫puntero, que es un puntero de pistola.

74
00:05:07,900 --> 00:05:11,820
‫Recuerde, usará ese tipo para encontrar el método para llamar.

75
00:05:11,830 --> 00:05:17,920
‫Entonces irá y llamará a este método de disparo en la parte superior en lugar del método anulado en pistola.

76
00:05:18,190 --> 00:05:22,780
‫Para que pueda llamar al método anulado en pistola, tendría que llamar.

77
00:05:22,780 --> 00:05:25,390
‫Tendría que tener un puntero de tipo pistola.

78
00:05:26,020 --> 00:05:27,490
‫Ahora que está bien.

79
00:05:27,490 --> 00:05:29,320
‫Y puedes ver por qué hacen esto.

80
00:05:29,320 --> 00:05:30,370
‫Es por eficiencia.

81
00:05:30,370 --> 00:05:32,200
‫C++ tiene que ver con la eficiencia.

82
00:05:32,500 --> 00:05:39,220
‫Si algo va a costar más cuando se compila, cuando se ejecuta, entonces C ++ no lo hará de forma predeterminada a menos

83
00:05:39,220 --> 00:05:40,420
‫que se lo solicite.

84
00:05:40,750 --> 00:05:46,240
‫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

85
00:05:46,240 --> 00:05:47,320
‫de puntero de pistola.

86
00:05:47,740 --> 00:05:50,040
‫Y aquí es donde entra Dynamic Dispatch.

87
00:05:50,050 --> 00:05:53,890
‫Este término elegante básicamente significa que no queremos que haga eso.

88
00:05:54,160 --> 00:05:59,910
‫Lo que queremos que haga es decir, espera un segundo, ¿qué está realmente almacenado en ese puntero de pistola?

89
00:05:59,920 --> 00:06:01,960
‫¿Cuál es el tipo real allí?

90
00:06:02,410 --> 00:06:06,040
‫Y el tipo real que nos damos cuenta es que es un tipo pistola.

91
00:06:06,310 --> 00:06:12,490
‫Entonces, debemos preguntarnos, ¿hay algún método para ese tipo que se anule?

92
00:06:12,490 --> 00:06:13,570
‫Y sí, lo hay.

93
00:06:13,600 --> 00:06:20,080
‫Entonces, ¿cómo le damos a C++ el permiso para ser un poco menos eficiente y nos da la capacidad de

94
00:06:20,290 --> 00:06:26,050
‫anular sin tener que cambiar ese tipo de puntero, lo que no siempre es necesariamente posible?

95
00:06:26,050 --> 00:06:31,660
‫De hecho, en muchos casos no es posible, como es el caso cuando tienes tu propia clase activa

96
00:06:31,660 --> 00:06:32,170
‫personalizada.

97
00:06:32,650 --> 00:06:38,350
‫Unreal no tiene el puntero configurado para apuntar a su clase en particular, lo que requeriría que cambien todo

98
00:06:38,350 --> 00:06:41,110
‫el motor cada vez que introduce una nueva clase.

99
00:06:41,350 --> 00:06:42,910
‫No, eso simplemente no es posible.

100
00:06:43,210 --> 00:06:46,210
‫Tienen un puntero a algo de tipo actuar para protagonizar.

101
00:06:46,450 --> 00:06:50,950
‫Entonces, cuando llamen a Begin Play, usted quería llamar a su método Begin Play.

102
00:06:50,950 --> 00:06:52,450
‫Así que tiene que ser virtual.

103
00:06:52,690 --> 00:06:54,160
‫Y esa es la clave aquí.

104
00:06:54,400 --> 00:07:02,440
‫Si ponemos virtual delante del método en la clase principal, esto ahora le indica a C++ que espera un segundo, si estoy llamando

105
00:07:02,440 --> 00:07:09,970
‫a disparar en un puntero de tipo puntero de pistola, necesito verificar que esto no sea así, por ejemplo , una

106
00:07:10,150 --> 00:07:14,080
‫pistola y que este método de disparo ha sido anulado.

107
00:07:14,500 --> 00:07:19,180
‫Entonces, si seguimos adelante y presionamos ejecutar ahora, pueden ver que obtenemos bang y luego pue.

108
00:07:19,570 --> 00:07:23,800
‫Así que está funcionando como esperábamos con despacho dinámico.

109
00:07:24,100 --> 00:07:30,340
‫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

110
00:07:30,340 --> 00:07:33,160
‫realmente en el puntero y llamar al método relevante.

111
00:07:34,030 --> 00:07:39,670
‫Ahora, hay un poco más de sintaxis que a menudo nos verá usar, y esa es la palabra

112
00:07:39,670 --> 00:07:40,420
‫clave override.

113
00:07:40,420 --> 00:07:45,280
‫Y lo coloca después de un método que está tratando de anular como virtual.

114
00:07:45,910 --> 00:07:53,590
‫Y, básicamente, la palabra clave anular no es estrictamente necesaria, ni tampoco lo es volver a poner virtual contra algo en

115
00:07:53,590 --> 00:07:56,160
‫la clase secundaria de un arma.

116
00:07:56,170 --> 00:07:59,140
‫Así que no tienes que poner virtual, pero no está de más hacerlo.

117
00:07:59,650 --> 00:08:06,490
‫Pero la anulación es particularmente útil porque nos permite asegurarnos de que tenemos el nombre

118
00:08:06,490 --> 00:08:07,000
‫correcto.

119
00:08:07,000 --> 00:08:10,480
‫Entonces, si presiono ejecutar, todo funciona como antes cuando tengo la anulación.

120
00:08:10,810 --> 00:08:17,230
‫Pero digamos que me equivoqué por error en el nombre de este método, así que no hago la anulación.

121
00:08:17,230 --> 00:08:20,680
‫Y lo había llamado un tirador de notas, por ejemplo.

122
00:08:20,950 --> 00:08:22,720
‫Copié mal el nombre.

123
00:08:22,720 --> 00:08:24,280
‫Lo escribí en lugar de copiarlo.

124
00:08:24,610 --> 00:08:28,960
‫Si presiono correr ahora, entonces verás, tenemos el mismo error nuevamente porque estamos tratando de enfriarnos para disparar.

125
00:08:29,320 --> 00:08:32,170
‫Por error lo anulamos incorrectamente.

126
00:08:32,410 --> 00:08:33,550
‫Va bang, bang.

127
00:08:34,060 --> 00:08:37,780
‫Entonces, la forma en que podría evitar esto es diciendo: Bueno, estoy tratando de anular algo.

128
00:08:37,780 --> 00:08:43,750
‫Así que puse mi palabra clave de anulación aquí, y si trato de compilarla ahora, puede ver que está diciendo que

129
00:08:43,750 --> 00:08:49,510
‫el tirador está marcado como anulado, pero no hay ningún método, ningún método virtual para anular, en cuyo caso

130
00:08:49,510 --> 00:08:52,360
‫puedo ir , Oh sí, lo he escrito mal.

131
00:08:52,360 --> 00:08:57,070
‫Así que voy a seguir adelante y corregir mi código y volver a disparar.

132
00:08:57,460 --> 00:08:59,290
‫Y ahora funciona como pretendía.

133
00:08:59,290 --> 00:09:04,130
‫Entonces, es solo un poco de seguridad adicional al poner esa anulación allí e instantáneamente esto.

134
00:09:04,180 --> 00:09:09,130
‫También nos protegería contra el caso de que lo que estamos tratando de anular no sea virtual.

135
00:09:09,130 --> 00:09:14,620
‫Si trato de hacer eso, puede ver que dice que está marcado como anulado, pero no

136
00:09:14,620 --> 00:09:19,210
‫lo anula porque esa clase principal no tiene una función virtual para disparar.

137
00:09:19,390 --> 00:09:25,540
‫Entonces, espero que esto le brinde una descripción general de cómo C ++ usa e implementa funciones virtuales y por

138
00:09:25,540 --> 00:09:28,090
‫qué tenemos que ser tan explícitos al respecto.

139
00:09:28,690 --> 00:09:32,860
‫Ahora, pensemos en algunos casos de uso más para funciones virtuales en general.

140
00:09:32,860 --> 00:09:34,690
‫Ya hemos visto algunos del motor.

141
00:09:34,690 --> 00:09:37,360
‫¿Dónde has visto virtual antes?

142
00:09:38,510 --> 00:09:40,150
‫¿Dónde te imaginas usándolo?

143
00:09:40,160 --> 00:09:45,050
‫Acabamos de ver un ejemplo de caso de uso en el que puede tener un arma y diferentes anulaciones de eso

144
00:09:45,050 --> 00:09:46,640
‫que implementan disparar de diferentes maneras.

145
00:09:47,390 --> 00:09:53,600
‫¿De qué otra manera podrías imaginar usar funciones virtuales para anular la funcionalidad en las clases principales?

146
00:09:53,600 --> 00:09:58,190
‫Cuando haya pensado en una respuesta a esas dos preguntas, vaya y siga el enlace a

147
00:09:58,190 --> 00:10:00,890
‫las discusiones en esta lección y publique su respuesta.

148
00:10:00,890 --> 00:10:05,600
‫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

149
00:10:05,600 --> 00:10:05,810
‫personas.

150
00:10:06,080 --> 00:10:11,150
‫Tal vez eso lo ayude a solidificar su comprensión de los métodos virtuales.

151
00:10:11,240 --> 00:10:12,230
‫Eso es todo por esta conferencia.

152
00:10:12,230 --> 00:10:15,500
‫Nos vemos en el próximo donde estaremos usando métodos virtuales en la ira.

