Pensar en C++ (Volumen 1) - Grupo ARCO
Pensar en C++ (Volumen 1) - Grupo ARCO Pensar en C++ (Volumen 1) - Grupo ARCO
✐ ✐ ✐ “Volumen1” — 2012/1/12 — 13:52 — page 378 — #416 ✐ Capítulo 13. Creación dinámica de objetos 13.1. Creación de objetos La creación de un objeto en C++ tiene lugar en dos pasos: 1. Asignación de memoria para el objeto. 2. Llamada al constructor. Aceptemos por ahora que este segundo paso ocurre siempre. C++ lo fuerza, debido a que el uso de objetos no inicializados es una de las causas más frecuentes de errores de programación. Siempre se invoca al constructor, sin importar cómo ni dónde se crea el objeto. El primero de estos pasos puede ocurrir de varios modos y en diferente momento: 1. Asignación de memoria en la zona de almacenamiento estático, que tiene lugar durante la carga del programa. El espacio de memoria asignado al objeto existe hasta que el programa termina. 2. Asignación de memoria en la pila, cuando se alcanza algún punto determinado durante la ejecución del programa (la llave de apertura de un bloque). La memoria asignada se vuelve a liberar de forma automática en cuanto se alcanza el punto de ejecución complementario (la llave de cierre de un bloque). Las operaciones de manipulación de la pila forman parte del conjunto de instrucciones del procesador y son muy eficientes. Por otra parte, es necesario saber cuantas variables se necesitan mientras se escribe el programa de modo que el copilador pueda generar el código correspondiente. 3. Asignación dinámica, en una zona de memoria libre llamada montículo (heap o free store). Se reserva espacio para un objeto en esta zona mediante la llamada a una función durante la ejecución del programa; esto significa que se puede decidir en cualquier momento que se necesita cierta cantidad de memoria. Esto conlleva la responsabilidad de determinar el momento en que ha de liberarse la memoria, lo que implica determinar el tiempo de vida de la misma que, por tanto, ya no está bajo control de las reglas de ámbito. A menudo, las tres regiones de memoria referidas se disponen en una zona contigua de la memoria física: área estática, la pila, y el montículo, en un orden determinado por el escritor del compilador. No hay reglas fijas. La pila puede estar en una zona especial, y puede que las asignaciones en el montículo se obtengan mediante petición de bloques de la memoria del sistema operativo. Estos detalles quedan normalmente ocultos al programador puesto que todo lo que se necesita conocer al respecto es que esa memoria estará disponible cuando se necesite. 13.1.1. Asignación dinámica en C C proporciona las funciones de su biblioteca estándar malloc() y sus variantes calloc() y realloc() para asignar, y free() para liberar bloques de memoria dinámicamente en tiempo de ejecución. Estas funciones son pragmáticas pero rudimentarias por lo que requieren comprensión y un cuidadoso manejo por parte del programador. El listado que sigue es un ejemplo que ilustra el modo de crear una instancia de una clase con estas funciones de C: //: C13:MallocClass.cpp 378 ✐ ✐ ✐ ✐
✐ ✐ ✐ “Volumen1” — 2012/1/12 — 13:52 — page 379 — #417 ✐ 13.1. Creación de objetos // Malloc with class objects // What you’d have to do if not for "new" #include "../require.h" #include // malloc() & free() #include // memset() #include using namespace std; class Obj { int i, j, k; enum { sz = 100 }; char buf[sz]; public: void initialize() { // Can’t use constructor cout
- Page 365 and 366: ✐ ✐ ✐ “Volumen1” — 2012
- Page 367 and 368: ✐ ✐ ✐ “Volumen1” — 2012
- Page 369 and 370: ✐ ✐ ✐ “Volumen1” — 2012
- Page 371 and 372: ✐ ✐ ✐ “Volumen1” — 2012
- Page 373 and 374: ✐ ✐ ✐ “Volumen1” — 2012
- Page 375 and 376: ✐ ✐ ✐ “Volumen1” — 2012
- Page 377 and 378: ✐ ✐ ✐ “Volumen1” — 2012
- Page 379 and 380: ✐ ✐ ✐ “Volumen1” — 2012
- Page 381 and 382: ✐ ✐ ✐ “Volumen1” — 2012
- Page 383 and 384: ✐ ✐ ✐ “Volumen1” — 2012
- Page 385 and 386: ✐ ✐ ✐ “Volumen1” — 2012
- Page 387 and 388: ✐ ✐ ✐ “Volumen1” — 2012
- Page 389 and 390: ✐ ✐ ✐ “Volumen1” — 2012
- Page 391 and 392: ✐ ✐ ✐ “Volumen1” — 2012
- Page 393 and 394: ✐ ✐ ✐ “Volumen1” — 2012
- Page 395 and 396: ✐ ✐ ✐ “Volumen1” — 2012
- Page 397 and 398: ✐ ✐ ✐ “Volumen1” — 2012
- Page 399 and 400: ✐ ✐ ✐ “Volumen1” — 2012
- Page 401 and 402: ✐ ✐ ✐ “Volumen1” — 2012
- Page 403 and 404: ✐ ✐ ✐ “Volumen1” — 2012
- Page 405 and 406: ✐ ✐ ✐ “Volumen1” — 2012
- Page 407 and 408: ✐ ✐ ✐ “Volumen1” — 2012
- Page 409 and 410: ✐ ✐ ✐ “Volumen1” — 2012
- Page 411 and 412: ✐ ✐ ✐ “Volumen1” — 2012
- Page 413 and 414: ✐ ✐ ✐ “Volumen1” — 2012
- Page 415: ✐ ✐ ✐ “Volumen1” — 2012
- Page 419 and 420: ✐ ✐ ✐ “Volumen1” — 2012
- Page 421 and 422: ✐ ✐ ✐ “Volumen1” — 2012
- Page 423 and 424: ✐ ✐ ✐ “Volumen1” — 2012
- Page 425 and 426: ✐ ✐ ✐ “Volumen1” — 2012
- Page 427 and 428: ✐ ✐ ✐ “Volumen1” — 2012
- Page 429 and 430: ✐ ✐ ✐ “Volumen1” — 2012
- Page 431 and 432: ✐ ✐ ✐ “Volumen1” — 2012
- Page 433 and 434: ✐ ✐ ✐ “Volumen1” — 2012
- Page 435 and 436: ✐ ✐ ✐ “Volumen1” — 2012
- Page 437 and 438: ✐ ✐ ✐ “Volumen1” — 2012
- Page 439 and 440: ✐ ✐ ✐ “Volumen1” — 2012
- Page 441 and 442: ✐ ✐ ✐ “Volumen1” — 2012
- Page 443 and 444: ✐ ✐ ✐ “Volumen1” — 2012
- Page 445 and 446: ✐ ✐ ✐ “Volumen1” — 2012
- Page 447 and 448: ✐ ✐ ✐ “Volumen1” — 2012
- Page 449 and 450: ✐ ✐ ✐ “Volumen1” — 2012
- Page 451 and 452: ✐ ✐ ✐ “Volumen1” — 2012
- Page 453 and 454: ✐ ✐ ✐ “Volumen1” — 2012
- Page 455 and 456: ✐ ✐ ✐ “Volumen1” — 2012
- Page 457 and 458: ✐ ✐ ✐ “Volumen1” — 2012
- Page 459 and 460: ✐ ✐ ✐ “Volumen1” — 2012
- Page 461 and 462: ✐ ✐ ✐ “Volumen1” — 2012
- Page 463 and 464: ✐ ✐ ✐ “Volumen1” — 2012
- Page 465 and 466: ✐ ✐ ✐ “Volumen1” — 2012
✐<br />
✐<br />
✐<br />
“Volum<strong>en</strong>1” — 2012/1/12 — 13:52 — page 378 — #416<br />
✐<br />
Capítulo 13. Creación dinámica de objetos<br />
13.1. Creación de objetos<br />
La creación de un objeto <strong>en</strong> <strong>C++</strong> ti<strong>en</strong>e lugar <strong>en</strong> dos pasos:<br />
1. Asignación de memoria para el objeto.<br />
2. Llamada al constructor.<br />
Aceptemos por ahora que este segundo paso ocurre siempre. <strong>C++</strong> lo fuerza, debido<br />
a que el uso de objetos no inicializados es una de las causas más frecu<strong>en</strong>tes<br />
de errores de programación. Siempre se invoca al constructor, sin importar cómo ni<br />
dónde se crea el objeto.<br />
El primero de estos pasos puede ocurrir de varios modos y <strong>en</strong> difer<strong>en</strong>te mom<strong>en</strong>to:<br />
1. Asignación de memoria <strong>en</strong> la zona de almac<strong>en</strong>ami<strong>en</strong>to estático, que ti<strong>en</strong>e lugar<br />
durante la carga del programa. El espacio de memoria asignado al objeto existe<br />
hasta que el programa termina.<br />
2. Asignación de memoria <strong>en</strong> la pila, cuando se alcanza algún punto determinado<br />
durante la ejecución del programa (la llave de apertura de un bloque). La<br />
memoria asignada se vuelve a liberar de forma automática <strong>en</strong> cuanto se alcanza<br />
el punto de ejecución complem<strong>en</strong>tario (la llave de cierre de un bloque). Las<br />
operaciones de manipulación de la pila forman parte del conjunto de instrucciones<br />
del procesador y son muy efici<strong>en</strong>tes. Por otra parte, es necesario saber<br />
cuantas variables se necesitan mi<strong>en</strong>tras se escribe el programa de modo que el<br />
copilador pueda g<strong>en</strong>erar el código correspondi<strong>en</strong>te.<br />
3. Asignación dinámica, <strong>en</strong> una zona de memoria libre llamada montículo (heap<br />
o free store). Se reserva espacio para un objeto <strong>en</strong> esta zona mediante la llamada<br />
a una función durante la ejecución del programa; esto significa que se puede<br />
decidir <strong>en</strong> cualquier mom<strong>en</strong>to que se necesita cierta cantidad de memoria. Esto<br />
conlleva la responsabilidad de determinar el mom<strong>en</strong>to <strong>en</strong> que ha de liberarse<br />
la memoria, lo que implica determinar el tiempo de vida de la misma que, por<br />
tanto, ya no está bajo control de las reglas de ámbito.<br />
A m<strong>en</strong>udo, las tres regiones de memoria referidas se dispon<strong>en</strong> <strong>en</strong> una zona contigua<br />
de la memoria física: área estática, la pila, y el montículo, <strong>en</strong> un ord<strong>en</strong> determinado<br />
por el escritor del compilador. No hay reglas fijas. La pila puede estar <strong>en</strong> una<br />
zona especial, y puede que las asignaciones <strong>en</strong> el montículo se obt<strong>en</strong>gan mediante<br />
petición de bloques de la memoria del sistema operativo. Estos detalles quedan<br />
normalm<strong>en</strong>te ocultos al programador puesto que todo lo que se necesita conocer al<br />
respecto es que esa memoria estará disponible cuando se necesite.<br />
13.1.1. Asignación dinámica <strong>en</strong> C<br />
C proporciona las funciones de su biblioteca estándar malloc() y sus variantes<br />
calloc() y realloc() para asignar, y free() para liberar bloques de memoria<br />
dinámicam<strong>en</strong>te <strong>en</strong> tiempo de ejecución. Estas funciones son pragmáticas pero rudim<strong>en</strong>tarias<br />
por lo que requier<strong>en</strong> compr<strong>en</strong>sión y un cuidadoso manejo por parte del<br />
programador. El listado que sigue es un ejemplo que ilustra el modo de crear una<br />
instancia de una clase con estas funciones de C:<br />
//: C13:MallocClass.cpp<br />
378<br />
✐<br />
✐<br />
✐<br />
✐