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.
Cree una función con una variable estática que sea un
puntero (con un argumento por defecto igual cero). Cuando
la función que realice la llamada proporcione un valor para
ese argumento se usará para apuntar al principio de un
array de int
. Si se llama a la función con el
argumento cero (utilizando el argumento por defecto), la
función devuelve el siguiente valor del array, hasta que
llegue a un valor -1
en el array (que
actuará como señal de final). Experimente con esta función en
main()
.
Cree una función que devuelva el siguiente valor de una
serie de Fibonacci cada vez que sea llamada. Añada un
argumento que de tipo bool
con valor por
defecto false
tal que cuando el argumento valga
true
«reinicie» la función al
principio de la serie de Fibonacci. Experimente con esta función en
main()
.
Cree una clase que contenga un array de
int
. Especifique la dimensión del array
utilizando static const int
dentro de la
clase. Añada una variable const int
e
inicialícela en la lista de inicialización del
constructor. Haga al constructor inline
. Añada un
atributo static int
e inicialícelo a un valor
específico. Añada un método estático que imprima el atributo
estático. Añada un miembro inline
llamado
print()
que imprima todos los valores
del array y que llame al método estático. Experimente con esta
clase en main()
.
Cree una clase llamada Monitor
que
mantenga el registro del número de veces que ha sido llamado
su método incident()
. Añada un método
print()
que muestre por pantalla el
número de incidentes. Ahora cree una función global (no un
método) que contenga un objeto estático
Monitor
. Cada vez que llame a la
función debe llamar a incident()
,
después al método print()
para sacar
por pantalla el contador de incidentes. Experimente con la función
en main()
.
Modifique la clase Monitor
del
Ejercicio 4 de forma que pueda decrementar
(decrement()
) el contador de
incidentes. Cree una clase llamada
Monitor2
que tome como argumento del
constructor un puntero a Monitor1
, y
que almacene ese puntero y llame a
incident()
y
print()
. En el destructor para
Monitor2
, llame a
decrement()
y
print()
. Cree ahora un objeto estático
de Monitor2
dentro de una
función. Dentro de main()
, experimente
llamando y no llamando a la función para ver qué pasa con el
destructor de Monitor2
.
Cree un objeto global de clase
Monitor2
y vea qué sucede.
Cree una clase con un destructor que imprima un mensaje y
después llame a exit()
. Cree un objeto
global de esa clase y vea qué pasa.
En StaticDestructors.cpp
, experimente
con el orden de llamada de los constructores y destructores
llamando a f()
y
g()
dentro de
main()
en diferentes órdenes. ¿Su
compilador inicializa los objetos de la forma correcta?
En StaticDestructors.cpp
, pruebe el
manejo de errores por defecto de su implementación
convirtiendo la definición original de
out
dentro de una declaración
extern
, y poniendo la definición real después de la
definición de a
(donde el constructor de
Obj
manda información a
out
). Asegúrese que no hay ningún otro
programa importante funcionando en su máquina cuando ejecute
el código o que su máquina maneje las faltas robustamente.
Pruebe que las variables estáticas de fichero en los
archivos de cabecera no chocan entre sí cuando son incluidas
en más de un archivo cpp
.
Cree una única clase que contenga un int
, un
constructor que inicialice el int
con su
argumento, un método que cambie el valor del
int
con su argumento y una función
print()
que muestre por pantalla el
int
. Coloque su clase en un archivo de cabecera
e incluya dicho archivo en dos archivos
cpp
. En uno de ellos cree una instancia
de la clase y en la otra declare ese identificador como
extern
y pruebe dentro de
main()
. Recuerde, debe enlazar los dos
archivos objeto o de lo contrario el enlazador no encontrará
el objeto.
Cree la instancia del objeto del Ejercicio 11 como static
y
verifique que, debido a eso, el enlazador es incapaz de encontrarla.
Declare una función en un archivo de cabecera. Defina la
función en un archivo cpp
y llámela
desde main()
en un segundo archivo
cpp
. Compile y verifique que
funciona. Ahora cambie la definición de la función de forma
que sea static
y verifique que el enlazador no
puede encontrarla.
Modifique Volatile.cpp
del Capítulo 8
para hacer que comm::isr()
funcione
realmente como una rutina de servicio de
interrupción. Pista: una rutina de servicio de interrupción
no toma ningún argumento.
Escriba y compile un único programa que utilice las palabras
clave auto
y register
.
Cree un archivo de cabecera que contenga un espacio de
nombres. Dentro del espacio de nombres cree varias
declaraciones de funciones. Cree ahora un segundo archivo de
cabecera que incluya el primero y continúe el espacio de
nombres, añadiendo varias declaraciones de funciones
más. Cree ahora un archivo cpp
que
incluya el segundo archivo de cabecera. Cambie su espacio de
nombres a otro nombre (más corto). Dentro de una definición
de función, llame a una de sus funciones utilizando la
resolución de ámbito. Dentro de una definición de función
separada, escriba una directiva using
para
introducir su espacio de nombres en el ámbito de esa
función, y demuestre que no necesita utilizar la resolución
de ámbito para llamar a las funciones desde su espacio de
nombres.
Cree un archivo de cabecera con un espacio de nombres sin
nombre. Incluya la cabecera en dos archivos
cpp
diferentes y demuestre que un
espacio sin nombre es único para cada :unidad de traducción.
Utilizando el archivo de cabecera del Ejercicio 17, demuestre que los nombres de un espacio de nombres sin nombre están disponibles automáticamente en una :unidad de traducción sin calificación.
Modifique FriendInjection.cpp
para
añadir una definición para la función amiga y para llamar a
la función desde main()
.
En Arithmetic.cpp
, demuestre que la
directiva using
no se extiende fuera de la función en
la que fue creada.
Repare el problema de
OverridingAmbiguity.cpp
, primero con
resolución de ámbito y luego, con una declaración
using
que fuerce al compilador a escojer uno de los
nombres de función idénticos.
En dos archivos de cabecera, cree dos espacios de nombres,
cada uno conteniendo una clase (con todas las definiciones
inline
) con idéntico nombre que el del otro espacio
de nombres. Cree un archivo cpp
que
incluya ambos archivos. Cree una función y, dentro de la
función, utilice la directiva using
para introducir
ambos espacios de nombres. Pruebe a crear un objeto de la
clase y vea que sucede. Haga las directivas using
globales (fuera de la función) para ver si existe alguna
diferencia. Repare el problema usando la resolución de
ámbito, y cree objetos de ambas clases.
Repare el problema del Ejercicio 22 con una declaración
using
que fuerce al compilador a escojer uno de los
nombres de clase idénticos.
Extraiga las declaraciones de espacios de nombres de
BobsSuperDuperLibrary.cpp
y
UnnamedNamespaces.cpp
y póngalos en
archivos separados, dando un nombre al espacio de nombres
sin nombre en el proceso. En un tercer archivo de cabecera,
cree un nuevo espacio de nombres que combine los elementos
de los otros dos espacios de nombres con declaraciones
using
. En main()
, introduzca
su nuevo espacio de nombres con una directiva using
y acceda a todos los elementos de su espacio de nombres.
Cree un archivo de cabecera que incluya
<string>
y
<iostream>
pero que no use ninguna
directiva using
ni ninguna declaración
using
. Añada guardas de inclusión como ha visto en
los archivos de cabecera del libro. Cree una clase con todas
las funciones inline
que muestre por pantalla el
string
. Cree un archivo
cpp
y ejercite su clase en
main()
.
Cree una clase que contenga un static double
y
long
. Escriba un método estático que imprima
los valores.
Cree una clase que contenga un int
, un
constructor que inicialice el int
con su
argumento, y una función print()
que
muestre por pantalla el int
. Cree ahora una
segunda clase que contenga un objeto estático de la
primera. Añada un método estático que llame a la función
print()
del objeto estático. Ejercitu
su clase en main()
.
Cree una clase que contenga un array estático de
int
constante y otro no constante. Escriba
métodos estáticos que impriman los arrays. Experimente con su clase
en main()
.
Cree una clase que contenga un string
, con un
constructor que inicialice el string
a partir
de su argumento, y una función print()
que imprima el string
. Cree otra clase que
contenga un array estático, tanto constante como no
constante, de objetos de la primera clase, y métodos
estáticos para imprimir dichos arrays. Experimente con la
segunda clase en main()
.
Cree una struct
que contenga un int
y
un constructor por defecto que inicialice el
int
a cero. Haga ese struct
local a
una función. Dentro de dicha función, cree un array de
objetos de su struct
y demuestre que cada
int
del array ha sido inicializado a cero
automáticamente.
Cree una clase que represente una conexión a impresora, y que sólo le permita tener una impresora.
En un archivo de cabecera, cree una clase
Mirror
que contiene dos atributos:
un puntero a un objeto Mirror
y un
bool
. Déle dos constructores: el constructor
por defecto inicializa el bool
a true
y el puntero a Mirror
a cero. El
segundo constructor toma como argumento un puntero a un
objeto Mirror
, que asigna al puntero
interno del objeto; pone el bool
a
false
. Añada un método test()
:
si el puntero del objeto es distinto de cero, devuelve el
valor de test()
llamado a través del
puntero. Si el puntero es cero, devuelve el
bool
. Cree ahora cinco archivos
cpp
, cada uno incluyendo la cabecera
Mirror
. El primer archivo
cpp
define un objeto
Mirror
global utilizando el
constructor por defecto. El segundo archivo declara el
objeto del primer archivo como extern
, y define un
objeto Mirror
global utilizando el
segundo constructor, con un puntero al primer objeto. Siga
haciendo lo mismo hasta que llegue al último archivo, que
también contendrá una definición de objeto global. En este
archivo, main()
debe llamar a la
función test()
e informar del
resultado. Si el resultado es true
, encuentre la
forma de cambiar el orden de enlazado de su enlazador y
cámbielo hasta que el resultado sea false
.
Repare el problema del Ejercicio 32 utilizando la técnica uno mostrada en este libro.
Repare el problema del Ejercicio 32 utilizando la técnica dos mostrada en este libro.
Sin incluir ningún archivo de cabecera, declare la función
puts()
de la Librería Estándar de C.
Llame a esa función desde main()
.