Pensar en C++ (Volumen 1) - Grupo ARCO
Pensar en C++ (Volumen 1) - Grupo ARCO
Pensar en C++ (Volumen 1) - Grupo ARCO
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
✐<br />
✐<br />
✐<br />
“Volum<strong>en</strong>1” — 2012/1/12 — 13:52 — page 271 — #309<br />
✐<br />
9.7. Comprobación de errores mejorada<br />
es más g<strong>en</strong>eral (quizá quiera utilizar esta forma <strong>en</strong> su propio código).<br />
En las definiciones para requireArgs() y requireMinArgs(), se añade uno<br />
al número de argum<strong>en</strong>tos que necesita <strong>en</strong> la línea de comandos porque argc siempre<br />
incluye el nombre del programa que está ejecutado como argum<strong>en</strong>to cero, y por eso<br />
siempre ti<strong>en</strong>e un valor que excede <strong>en</strong> uno al número real de argum<strong>en</strong>tos de la línea<br />
de comandos.<br />
Fíjese <strong>en</strong> el uso de declaraciones locales using namespace std con cada función.<br />
Esto es porque algunos compiladores <strong>en</strong> el mom<strong>en</strong>to de escribir este libro incluy<strong>en</strong><br />
incorrectam<strong>en</strong>te las funciones de la librería C estándar <strong>en</strong> el espacio de nombres<br />
std, así que la cualificación explícita podría causar un error <strong>en</strong> tiempo de compilación.<br />
Las declaraciones locales permit<strong>en</strong> que require.h funcione tanto con librerías<br />
correctas como con incorrectas sin abrir el espacio de nombres std para cualquiera<br />
que incluya este fichero de cabecera.<br />
Aquí hay un programa simple para probar requite.h:<br />
//: C09:ErrTest.cpp<br />
//{T} ErrTest.cpp<br />
// Testing require.h<br />
#include "../require.h"<br />
#include <br />
using namespace std;<br />
int main(int argc, char* argv[]) {<br />
int i = 1;<br />
require(i, "value must be nonzero");<br />
requireArgs(argc, 1);<br />
requireMinArgs(argc, 1);<br />
ifstream in(argv[1]);<br />
assure(in, argv[1]); // Use the file name<br />
ifstream nofile("nofile.xxx");<br />
// Fails:<br />
//! assure(nofile); // The default argum<strong>en</strong>t<br />
ofstream out("tmp.txt");<br />
assure(out);<br />
} ///:~<br />
Podría estar t<strong>en</strong>tado a ir un paso más allá para manejar la apertura de ficheros y<br />
añadir una macro a require.h.<br />
#define IFOPEN(VAR, NAME) \<br />
ifstream VAR(NAME); \<br />
assure(VAR, NAME);<br />
Que podría usarse <strong>en</strong>tonces así:<br />
IFOPEN(in, argv[1])<br />
En principio, esto podría parecer atractivo porque significa que hay que escribir<br />
m<strong>en</strong>os. No es terriblem<strong>en</strong>te inseguro, pero es un camino que es mejor evitar. Fíjese<br />
que, de nuevo, una macro parece una función pero se comporta difer<strong>en</strong>te; realm<strong>en</strong>te<br />
se está creando un objeto in cuyo alcance persiste más allá de la macro. Quizá lo<br />
<strong>en</strong>ti<strong>en</strong>da, pero para programadores nuevos y mant<strong>en</strong>edores de código sólo es una<br />
271<br />
✐<br />
✐<br />
✐<br />
✐