Guest User

Untitled

a guest
Mar 24th, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.01 KB | None | 0 0
  1. /*
  2. * Constructores para la clase AES.
  3. * Para simplificar, estoy suponiendo que solo hay un arreglo
  4. * miembro (la llave), en lugar de tres.
  5. */
  6.  
  7. /*
  8. * Constructor normal: recibe el tamaño de llave y reserva
  9. * el espacio para el arreglo de la llave.
  10. */
  11.  
  12. AES::AES(int tamanioLlave)
  13. : mTamanioLlave {tamanioLlave},
  14. mLlave {new unsigned char [mTamanioLlave]}
  15. {
  16. }
  17.  
  18. /*
  19. * Constructor por copia: crea un nuevo objeto a partir de
  20. * la referencia dada.
  21. *
  22. * Se usa delegación de constructores: primero se manda a llamar
  23. * al anterior, este reserva memoria, y luego aquí se hace la
  24. * copia solamente
  25. *
  26. * Es importante notar que esta operación toma O(n) pasos en
  27. * llevarse a cabo, ya que es una copia. Perdón por escribir lo obvio:
  28. * al terminar esta operación tienes dos objetos AES con lo
  29. * mismo.
  30. */
  31.  
  32. AES::AES(const AES& original)
  33. : AES{original.mTamanioLlave}
  34. {
  35. memcpy(mLlave, original.mLlave, mTamanioLlave);
  36. }
  37.  
  38. /*
  39. * Asignación por copia.
  40. */
  41.  
  42. AES& AES::operator=(const AES& original)
  43. {
  44. mTamanioLlave = original.mTamanioLlave;
  45. delete[] mLlave;
  46. mLlave = new unsigned char[mTamanioLlave];
  47. memcpy(mLlave, original.mLlave, mTamanioLlave);
  48. return *this;
  49. }
  50.  
  51. /*
  52. * Constructor por movimiento. Igual que la copia, crea
  53. * un nuevo objeto a partir de la referencia dada; la diferencia
  54. * es que esta referencia es de tipo rvalue (una referencia a algo
  55. * que puede ir del lado derecho en una expresión). Creo que no
  56. * acabaría si intento entrar en detalles sobre las diferencias entre
  57. * lvalue y rvalue. Lo importante aquí es que este constructor
  58. * tiene la garantía de que el objeto fuente (original) ya no se va
  59. * a volver a usar, por lo tanto, en lugar de copiar el contenido
  60. * del arreglo, simplemente hay que hacer que el apuntador apunte
  61. * (valga la redundancia) a la misma dirección de memoria.
  62. *
  63. * Importante: esta operación es constante O(1). Al final, queda un
  64. * nuevo objeto AES igual al anterior, y uno vacío, que ya no se
  65. * puede usar.
  66. *
  67. * En la lista de inicialización se inicializa el tamaño de llave y
  68. * el apuntador interno (ojo, solo se actualiza el apuntador, no
  69. * se copia el contenido de todo el arreglo). En el cuerpo se deja
  70. * inutilizable al objeto anterior. Lo importate es hacer nullptr
  71. * su arreglo interno, para que cuando se llame al desctructor,
  72. * este no libere la memoria (ya que esa memoria es la misma que
  73. * está ocupando el nuevo objeto).
  74. */
  75.  
  76. AES::AES(AES &&original)
  77. : mTamanioLlave {original.mTamanioLlave},
  78. mLlave {original.mLlave}
  79. {
  80. original.mTamanioLlave = 0;
  81. original.mLlave = nullptr;
  82. }
  83.  
  84. /*
  85. * Asignación por referencia a rvalue (por movimiento).
  86. */
  87.  
  88. AES::operator=(AES &&original)
  89. {
  90. mTmanioLlave = original.mTamanioLlave;
  91. delete[] mLlave; /* Importante: liberar memoria anterior. */
  92. mLlave = original.mLlave;
  93. original.mTamanioLlave = 0;
  94. original.mLlave = nullptr;
  95. return *this;
  96. }
  97.  
  98. /*
  99. * Destructor. Libera la memoria.
  100. */
  101.  
  102. AES::~AES()
  103. {
  104. delete[] mLlave;
  105. }
  106.  
  107. /*
  108. * Ahora, algunos ejemplos de cuando se manda llamar por defecto
  109. * a cada constructor y a cada operación de asignación:
  110. */
  111.  
  112. AES funcionDePrueba(AES argumento);
  113.  
  114. int main ()
  115. {
  116. /* Constructor normal: */
  117. AES prueba {5};
  118.  
  119. /* Constructor por copia: */
  120. AES pruebaDos {prueba};
  121.  
  122. /* Constructor por movimiento: */
  123. AES pruebaTres {std::move(prueba)};
  124.  
  125. /* Asignación por copia: */
  126. pruebaTres = pruebaDos;
  127.  
  128. /* Asignación por movimiento: */
  129. pruebaDos = std::move(pruebaTres);
  130.  
  131. /* Aquí hay varios:
  132. * Primero, se utiliza el constructor por copia para poner
  133. * el contenido de pruebaDos en el contexto de la función.
  134. * Segundo, se utiliza el constructor por movimiento cuando
  135. * la función regresa. */
  136. AES pruebaCinco = funcionDePrueba(pruebaDos);
  137. }
  138.  
  139. /*
  140. * std::move regresa un rvalue del objeto dado (el nombre
  141. * no es muy descriptivo).
  142. *
  143. * Es importante notar como la operación por movimiento solo
  144. * se utiliza de forma normal cuando las funciones regresan;
  145. * para llamarla de forma explícita hay que utilizar std::move.
  146. *
  147. * Una vez que se conoce cómo funcionan ambas operaciones,
  148. * se pueden ocupar para hacer diseños más eficientes. En particular,
  149. * siempre que se esté seguro de ya no ocupar un objeto, hay que
  150. * utilizar la operación de movimiento (evitando hacer copias
  151. * inútiles). Por ejemplo, considere estas dos versiones de
  152. * una operación de intercambio (swap):
  153. */
  154.  
  155. void swapUno(AES uno, AES dos)
  156. {
  157. AES temporal = uno;
  158. uno = dos;
  159. dos = temporal;
  160. }
  161.  
  162. void swapDos(AES uno, AES dos)
  163. {
  164. AES temporal = std::move(uno);
  165. uno = std::move(dos);
  166. dos = std::move(temporal);
  167. }
  168.  
  169. /* Ambas hacen lo mismo, sin embargo la primera ocupa copias
  170. * y la segunda movimientos: la primera está en el orden de
  171. * O(3 * n), mentras que la segunda solo actualiza apuntadores
  172. * O(3). Puede parecer una ventaja un tanto menor, sin embargo
  173. * esto depende totalmente del tamaño del arreglo interno; este
  174. * puede tener tanto 10 elementos, como 10 millones, en cuyo caso
  175. * la primera versión del swap es totalmente ineficiente.
  176. */
Add Comment
Please, Sign In to add comment