Las soluciones a los ejercicios se pueden encontrar en el documento electrónico titulado «The Thinking in C++ Annotated Solution Guide», disponible por poco dinero en www.BruceEckel.com.
Implemente la jerarquía de herencia del diagrama de
OShape
de este capítulo.
Modifique el resultado del Ejercicio 1 del capítulo 15 para
usar la Stack
y el
iterator
en TStack2.h
en vez de un array de punteros a
Shape
. Añada destructores a la
jerarquía de clases para que se pueda ver que los objetos
Shape
han sido destruidos cuando la
Stack
se sale del ámbito.
Modifique TPStash.h
para que el valor
de incremento usado por inflate()
pueda ser cambiado durante la vida de un objeto contenedor
particular.
Modifique TPStash.h
para que el valor de
incremento usado por inflate()
automáticamente cambie de tamaño para que reduzca el número
de veces que debe ser llamado. Por ejemplo, cada vez que se
llama podría doblar el valor de incremento para su uso en la
siguiente llamada. Demuestre la funcionalidad mostrando cada
vez que se llama a inflate()
, y escriba
código de prueba en main()
.
Convierta en plantilla la función de fibonacci()
con los tipos que puede producir (puede generar
long
, float
, etc. en vez de sólo
int
).
Usar el vector
de la STL como
implementación subyacente, para crear una platilla
Set
que acepte solo uno de cada tipo
de objeto que se aloje en él. Cree un iterador anidado que
soporte el concepto de "marcador final" de este
capítulo. Escriba código de prueba para el Set
en el main()
, y entonces
sustituyalo por la plantilla set
de
la STL para comprobar que el comportamiento es correcto.
Modifique AutoCounter.h
para que pueda
ser usado como un objeto miembro dentro de cualquier clase
cuya creación y destrucción quiera comprobar. Añada un
miembro string
para que contenga el
nombre de la clase. Compruebe esta herramienta dentro una
clase suya.
Cree una versión de OwnerStack.h
que use
un vector
de la Librería Estándar de C++
como su implementación subyacente. Será necesario conocer
algunas de las funciones miembro de vector
para poder hacerlo (sólo hay que mirar en el
archivo cabecera <vector>).
Modifique ValueStack.h
para que pueda
expandirse dinámicamente según se introduzcan más objetos y
se quede sin espacio. Cambie ValueStackTest.cpp
para comprobar su nueva funcionalidad.
Repita el ejercicio 9 pero use el vector
de la STL como la implementación interna de
ValueStack
. Note lo sencillo que es.
Modifique ValueStackTest.cpp
para que
use un vector
de la STL en vez de un
Stack
en el
main()
. Dése cuenta del comportamiento
en tiempo de ejecución: ¿Se genera un grupo de objetos por
defecto cuando se crea el vector
?
Modifique TStack2.h
para que use un
vector
de la STL. Asegurese de que no
cambia la interfaz, para que TStack2Test.cpp
funcione sin cambiarse.
Repita el Ejercicio 12 usando una stack
de la Librería Estándar de C++ en vez de un
vector
.
Modifique TPStash2.h
para que use un
vector
de la STL como su
implementación interna. Asegurese que no cambia la interfaz,
por lo que TPStash2Test.cpp
funciona
sin modificarse.
En IterIntStack.cpp
, modifique
IntStackIter
para darle un
constructor de «marcador final», y añada el
operator==
y el operator!=
. En el
main()
, use un iterador para moverse a
través de los elementos del contenedor hasta que se
encuentre el marcador.
Use TStack2.h
,
TPSTash2.h
, y
Shape.h
, instancie los contenedores
PStash
y Stack
para que contenga
Shape*
, rellene cada uno con punteros
a Shape
, entonces use iteradores para
moverse a través de cada contenedor y llame a
draw()
para cada objeto.
Cree una plantilla en la clase Int
para
que pueda alojar cualquier tipo de objetos (Siéntase libre
de cambiar el nombre de la clase a algo más apropiado).
Cree una plantilla de la clase IntArray
en IostreamOperatorOverloading.cpp
del capítulo 12, introduzca en plantilla ambos
tipos de objetos que están contenidos y el tamaño del array
interno
Convierta ObjContainer
en
NestedSmartPointer.cpp
del Capítulo 12
en una plantilla. Compruebelo con dos clases diferentes.
Modifique C15:OStack.h
y
C15:OStackTest.cpp
consiguiendo que
class Stack
pueda tener múltiple
herencia automáticamente de la clase contenida y de
Object
. La Stack
contenida debe aceptar y producir sólo punteros
del tipo contenido.
Repita el ejercicio 20 usando vector
en vez de Stack
.
Herede una clase StringVector
de
vector<void>
y redefina las
funciones miembro push_back()
y el
operator[]
para que acepten y produzcan
únicamente string*
(y realizen el
moldeado adecuado). Ahora creee una plantilla que haga
automáticamente lo mismo a una clase contenedora para
punteros de cualquier tipo. Esta técnica es a menudo usada
para reducir el código producido por muchas instanciaciones
de templates.
En TPStash2.h
, añada y compruebe un
operator-
para
PStash::iterator
, siguiendo la lógica
de operator+
.
En Drawing.cpp
, añada y compruebe una
plantilla de función que llame a funciones miembro
erase()
.
(Avanzado) Modifique la clase Stack
en TStack2.h
para permitir una
granularidad de la propiedad: Añada una bandera para cada
enlace indicando si el enlace posee el objeto al que apunta,
y de soporte a esta información la función push()
y en el destructor. Añada funciones miembro para
leer y cambiar la propiedad de cada enlace.
(Avanzado) Modifique PointerToMemberOperator.cpp
del Capítulo 12 para que la
FunctionObject
y el operator->*
sean convertidos en
plantillas para que funcionen con cualquier tipo de retorno
(para operator->*
, tendrá
que usar plantillas miembro descritas
en el Volumen 2). Añada soporte y compruebe para cero, uno y
dos argumentos en las funciones miembro
Dog
.