Advertisement
Guest User

Untitled

a guest
Jun 17th, 2019
271
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.05 KB | None | 0 0
  1. Capitulo 8: Programacion Orientada a Objetos.
  2.  
  3. Escribir programas en OOP implica pensar en nuestros programas a alto nivel.
  4. Las clases en C++ nos permiten agrupar datos en forma de variables, y funciones conocidas
  5. como metodos, que operan con los datos. Las clases nos permiten marcar variables y
  6. metodos para ocultarlos al resto del programa.
  7. Este concepto de ocultar datos se llama encapsulacion.
  8. La interfaz pública que escribamos tendra en cierta manera un comportamiento predecible
  9. para otras clases. Esta interfaz será consistente con el objetivo de crear programas
  10. fácilmente mantenibles. En cambio los datos privados y metodos pueden ser modificados
  11. tan frecuentemente como nosotros necesitemos. Por defecto los miembros y metodos de nuestra
  12. clase seran privados.
  13. Si tenemos variables miembro públicas, esto rompería la encapsulación.
  14. La manera de solucionar este problema es utilizar metodos para acceder a las variables.
  15.  
  16. class Jugador
  17. {
  18.  
  19. private:
  20. std::string m_nombre;
  21. public:
  22. void Nombrar(const std::string& nombre)
  23. {
  24. m_nombre = nombre;
  25. }
  26.  
  27. const std::string& ObtenerNombre() const
  28. {
  29. return m_nombre;
  30. }
  31.  
  32. };
  33.  
  34.  
  35. string nombre;
  36. cin >> nombre;
  37. jugador.Nombrar(nombre);
  38.  
  39. Cuando usas la palabra clave class informas al compilador para que cree un nuevo tipo de
  40. dato. Cuando se crea una variable, la primera tarea a ser realizada es inicializarla. C++
  41. nos ofrece metodos denominados constructores que son llamados cuando nuestra clase
  42. es inicializada. Ahora anhadiremos el constructor a la clase que creamos previamente:
  43.  
  44. class Jugador
  45. {
  46.  
  47. private:
  48. std::string m_nombre;
  49. public:
  50. Jugador(const std::string& nombre)
  51. : m_nombre(nombre)
  52. //En caso de querer anhadir mas variables a la lista de inicializacion,
  53. // usaremos la coma (,) en lugar de los dos puntos (:) para las siguientes variables.
  54. {
  55. }
  56.  
  57. void Nombrar(const std::string& nombre)
  58. {
  59. m_nombre = nombre;
  60. }
  61.  
  62. const std::string& ObtenerNombre() const
  63. {
  64. return m_nombre;
  65. }
  66.  
  67. };
  68.  
  69. Este codigo dara error si lo implementamos tal cual en nuestro programa debido a que
  70. nuestro constructor tiene un parametro string, lo que implica que debemos pasar un
  71. string a jugador.
  72. El problema estaria en: Jugador jugador;
  73. Para solucionarlo,
  74. puedes pasar el string a jugador: Jugador jugador("NombrePorDefecto");
  75. o anhadiendo tu propio constructor por defecto:
  76.  
  77. class Jugador
  78. {
  79.  
  80. private:
  81. std::string m_nombre;
  82. public:
  83. Jugador()
  84. {
  85. }
  86.  
  87. Jugador(const std::string& nombre)
  88. : m_nombre(nombre)
  89. {
  90. }
  91.  
  92. void Nombrar(const std::string& nombre)
  93. {
  94. m_nombre = nombre;
  95. }
  96.  
  97. const std::string& ObtenerNombre() const
  98. {
  99. return m_nombre;
  100. }
  101.  
  102. };
  103.  
  104.  
  105. Si anhades constructores por defecto a tus clases dependera principalmente de si hacerlo
  106. es valido.
  107. No todas las clases tienen sentido cuando no se les pasan valores para inicializarlos.
  108. Los constructores de clase son llamados cuando objetos del tipo de nuestra clase son
  109. creados.
  110. Los destructores de clase son llamados cuando nuestros objetos estan siendo destruidos.
  111. Los objetos pueden destruirse de diversas formas.
  112. En el siguiente codigo de ejemplo, acutalmente solo se destruyen objetos cuando estos
  113. se van fuera del dominio.
  114.  
  115. int main()
  116. {
  117. Jugador jugador;
  118. BucleDelJuego::SaludarAlJugador(jugador);
  119.  
  120. bool EstaJugando = true;
  121. while (EstaJugando)
  122. {
  123. EstaJugando = BucleDelJuego::IniciarPartida();
  124. }
  125.  
  126. return 0;
  127. }
  128.  
  129. El constructor de Jugador es llamado cuando se crea la variable jugador. Este codigo llama
  130. al constructor por defecto. La variable jugador se va fuera de dominio cuando la funcion
  131. que la contiene retorna (return). Entonces el destructor es llamado automaticamente tras
  132. el return.
  133.  
  134. class Jugador
  135. {
  136.  
  137. private:
  138. std::string m_nombre;
  139. public:
  140. Jugador()
  141. {
  142. }
  143.  
  144. Jugador(const std::string& nombre)
  145. : m_nombre(nombre)
  146. {
  147. }
  148.  
  149. ~Jugador() //Este es el destructor.
  150. {
  151. }
  152.  
  153. void Nombrar(const std::string& nombre)
  154. {
  155. m_nombre = nombre;
  156. }
  157.  
  158. const std::string& ObtenerNombre() const
  159. {
  160. return m_nombre;
  161. }
  162.  
  163. };
  164.  
  165.  
  166. El destructor se crea con una funcion con el nombre de la clase, precedido este por el
  167. simbolo ~
  168. Todas las clases tienen metodos destructores. En caso de no tenerlo y al igual que con los
  169. constructores, el compilador se encargara de crear unos por defecto.
  170.  
  171. Cuando nos referimos al codigo de una clase, nos referimos a el como clases.
  172. Cuando nos referimos a variables que son del tipo de la clase, nos referimos a ellas como
  173. objetos.
  174. La clase es el tipo de dato, y los objetos una instancia de la clase.
  175.  
  176. Sobrecarga de metodos:
  177. C++ nos permite crear distintos metodos compartiendo el mismo nombre pero que reciben
  178. diferentes parametros de entrada. Ejemplo:
  179.  
  180. class Jugador
  181. {
  182. private:
  183. std::string m_nombre;
  184. public:
  185. Jugador()
  186. {
  187. }
  188.  
  189. Jugador(const std::string& nombre)
  190. : m_nombre(nombre)
  191. {
  192. }
  193.  
  194. ~Jugador()
  195. {
  196. }
  197.  
  198. void Nombrar(const std::string& NombreDePila, const std::string& apellido)
  199. {
  200. m_nombre = NombreDePila;
  201. m_nombre.append(" ");
  202. m_nombre.append(apellido);
  203. }
  204.  
  205. void Nombrar(const std::string& nombre)
  206. {
  207. m_nombre = nombre;
  208. }
  209.  
  210.  
  211. const std::string& ObtenerNombre() const
  212. {
  213. return m_nombre;
  214. }
  215.  
  216. };
  217.  
  218. Puedes llamar a los metodos Nombrar de la siguiente manera:
  219.  
  220. jugador.Nombrar("Manolo");
  221. jugador.Nombrar("Manuel", "Perez")
  222.  
  223. El compilador trabaja automaticamente llamando al metodo correspondiente segun los
  224. parametros de entrada.
  225.  
  226. Metodos que solo tienen valores de retorno diferente daran error de compilacion.
  227.  
  228. A parte de poder sobrecargar metodos, tambien podemos sobrecargar operadores:
  229.  
  230. class Jugador
  231. {
  232. private:
  233. std::string m_nombre;
  234. public:
  235. Jugador()
  236. {
  237. }
  238.  
  239. Jugador(const std::string& nombre)
  240. : m_nombre(nombre)
  241. {
  242. }
  243.  
  244. ~Jugador()
  245. {
  246. }
  247.  
  248. void Nombrar(const std::string& NombreDePila, const std::string& apellido)
  249. {
  250. m_nombre = NombreDePila;
  251. m_nombre.append(" ");
  252. m_nombre.append(apellido);
  253. }
  254.  
  255. void Nombrar(const std::string& nombre)
  256. {
  257. m_nombre = nombre;
  258. }
  259.  
  260. void operator+=(const std::string& nombre) //Operador sobrecargado.
  261. {
  262. m_nombre.append(nombre);
  263. }
  264.  
  265.  
  266. const std::string& ObtenerNombre() const
  267. {
  268. return m_nombre;
  269. }
  270.  
  271. };
  272.  
  273.  
  274. Haremos la llamada de la siguiente forma:
  275.  
  276. jugador.Nombrar("Manolo");
  277. jugador += " Perez";
  278.  
  279. Algunas veces no vas a querer modificar el objeto pero te gustaria anhadir el nombre al
  280. string pasado y almacenar un valor de retorno. Tendra mas sentido sobrecargar el operador
  281. + en ese caso:
  282.  
  283. std::string operator+(const std::string& nombre)
  284. {
  285. std::string obtener(m_nombre);
  286. obtener.append(nombre);
  287. return obtener;
  288. }
  289. Esta funcion anhade el string pasado por parametro al miembro m_nombre y devuelve un nuevo
  290. string creado para almacenar el resultado. Podremos usar el operador de la siguiente
  291. manera:
  292.  
  293. jugador.Nombrar("Manolo");
  294. string NombreCompleto = jugador + " Perez";
  295.  
  296. Los ejemplos que estamos viendo tienen una desventaja, no podemos encadenar los operadores
  297. juntos.
  298. Para eso tenemos el operador de asignacion que nos permite encadenar.
  299.  
  300. const Jugador& operator=(const Jugador& jugador)
  301. {
  302. m_nombre = jugador.nombre;
  303. return this*;
  304. }
  305.  
  306. El puntero this guarda la direccion en memoria para el objeto actual. Nuestro operador =
  307. devuelve una referencia constante al objeto actual Jugador. Ejemplo:
  308.  
  309. void SaludarAlJugador(Jugador& jugador);
  310. {
  311. cout << "Bienvenido!" << endl;
  312. cout << "Como te llamas?" << endl;
  313.  
  314. string nombre;
  315. cin >> nombre;
  316. jugador.Nombrar("Manolo");
  317. Jugador jugador1, jugador2, jugador3, jugador4;
  318. jugador1 = jugador2 = jugador3 = jugador4 = jugador; //Cadena con el operador =
  319.  
  320. cout << endl << "Hola " << jugador.ObtenerNombre() << endl;
  321. }
  322.  
  323. El operador nos a permitido asignar el valor de jugador a todos los Objetos de Jugador
  324. que acabamos de crear. El orden de asignaciones es el siguiente:
  325. jugador4 = jugador;
  326. jugador3 = jugador4;
  327. jugador2 = jugador3;
  328. jugador1 = jugador2;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement