13.01.2015 Views

Pensar en C++ (Volumen 1) - Grupo ARCO

Pensar en C++ (Volumen 1) - Grupo ARCO

Pensar en C++ (Volumen 1) - Grupo ARCO

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

✐<br />

✐<br />

✐<br />

“Volum<strong>en</strong>1” — 2012/1/12 — 13:52 — page 159 — #197<br />

✐<br />

4.7. Conveciones para los ficheros de cabecera<br />

hacía eso a veces para acelerar un poquito la compilación evitando la tarea de abrir<br />

e incluir el fichero (eso no supone v<strong>en</strong>taja alguna con los compiladores modernos).<br />

Por ejemplo, la sigui<strong>en</strong>te es una declaración extremadam<strong>en</strong>te vaga de la función p-<br />

rintf() (de ):<br />

printf(...);<br />

Estos puntos susp<strong>en</strong>sivos 4 especifican una lista de argum<strong>en</strong>tos variable 5 , que dice:<br />

la printf() ti<strong>en</strong>e algunos argum<strong>en</strong>tos, cada uno con su tipo, pero no se sabe<br />

cuales. Simplem<strong>en</strong>te, coge los argum<strong>en</strong>tos que veas y aceptalos. Usando este tipo de<br />

declaración, se susp<strong>en</strong>d<strong>en</strong> todas las comprobaciones de errores <strong>en</strong> los argum<strong>en</strong>tos.<br />

Esta práctica puede causar problemas sutiles. Si declara funciones «a mano», <strong>en</strong><br />

un fichero puede cometer un error. Dado que el compilador sólo verá las declaraciones<br />

hechas a mano <strong>en</strong> ese fichero, se adaptará al error. El programa <strong>en</strong>lazará correctam<strong>en</strong>te,<br />

pero el uso de la función <strong>en</strong> ese fichero será defectuoso. Se trata de un error<br />

difícil de <strong>en</strong>contrar, y que se puede evitar fácilm<strong>en</strong>te usando el fichero de cabecera<br />

correspondi<strong>en</strong>te.<br />

Si se colocan todas las declaraciones de funciones <strong>en</strong> un fichero de cabecera, y se<br />

incluye ese fichero allí donde se use la función se asegurará una declaración consist<strong>en</strong>te<br />

a través del sistema completo. También se asegurará de que la declaración y la<br />

definición correspond<strong>en</strong> incluy<strong>en</strong>do el fichero de cabecera <strong>en</strong> el fichero de definición.<br />

Si declara una struct <strong>en</strong> un fichero de cabecera <strong>en</strong> <strong>C++</strong>, debe incluir ese fichero<br />

allí donde se use una struct y también donde se definan los métodos de la s-<br />

truct. El compilador de <strong>C++</strong> devolverá un m<strong>en</strong>saje de error si int<strong>en</strong>ta llamar a<br />

una función, o llamar o definir un método, sin declararla primero. Imponi<strong>en</strong>do el<br />

uso apropiado de los ficheros de cabecera, el l<strong>en</strong>guaje asegura la consist<strong>en</strong>cia de las<br />

librerías, y reduce el número de error forzando que se use la misma interface <strong>en</strong><br />

todas partes.<br />

El fichero de cabecera es un contrato <strong>en</strong>tre el programador de la librería y el que<br />

la usa. El contrato describe las estructuras de datos, expone los argum<strong>en</strong>tos y valores<br />

de retorno para las funciones. Dice, «Esto es lo que hace mi librería». El usuario necesita<br />

parte de esta información para desarrollar la aplicación, y el compilador necesita<br />

toda ella para g<strong>en</strong>erar el código correcto. El usuario de la struct simplem<strong>en</strong>te incluye<br />

el fichero de cabecera, crea objetos (instancias) de esa struct, y <strong>en</strong>laza con el<br />

módulo objeto o librería (es decir, el código compilado)<br />

El compilador impone el contrato obligando a declarar todas las estruturas y funciones<br />

antes que puedan ser usadas y, <strong>en</strong> el caso de métodos, antes de ser definidos.<br />

De ese modo, se le obliga a poner las declaraciones <strong>en</strong> el fichero de cabecera e incluirlo<br />

<strong>en</strong> el fichero <strong>en</strong> el que se defin<strong>en</strong> los métodos y <strong>en</strong> los ficheros <strong>en</strong> los que se<br />

us<strong>en</strong>. Como se incluye un único fichero que describe la librería para todo el sistema,<br />

el compilador puede asegurar la consist<strong>en</strong>cia y evitar errores.<br />

Hay ciertos asuntos a los que debe prestar at<strong>en</strong>ción para organizar su código<br />

apropiadam<strong>en</strong>te y escribir ficheros de cabecera eficaces. La regla básica es «únicam<strong>en</strong>te<br />

declaraciones», es decir, sólo información para el compiladore pero nada que<br />

requiera alojami<strong>en</strong>to <strong>en</strong> memoria ya sea g<strong>en</strong>erando código o creando variables. Esto<br />

es así porque el fichero de cabecera normalm<strong>en</strong>te se incluye <strong>en</strong> varias unidades de<br />

4 (N. de T. ellipsis) <strong>en</strong> inglés)<br />

5 Para escribir una definición de función que toma una lista de argum<strong>en</strong>tos realm<strong>en</strong>te variable, debe<br />

usar varargs, aunque se debería evitar <strong>en</strong> <strong>C++</strong>. Puede <strong>en</strong>contar información detallada sobre el uso de<br />

varargs <strong>en</strong> un manual de C.<br />

159<br />

✐<br />

✐<br />

✐<br />

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!