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

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 />

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

Saved successfully!

Ooh no, something went wrong!