[C con Clase] Varias dudas del curso

Salvador Pozo salvador en conclase.net
Vie Nov 23 19:10:59 CET 2007


El pasado 2007-11-23 17:18:15, David Reza escribió:
 
Hola:

DR> Tengo otra duda que me ha surgido.
DR> ¿Qué utilidad tiene el namespace std? y ¿por qué al utilizarlo se omite la
DR> extensión de los archivos de encabezado?

Esto se explica con detalle en un capítulo posterior del curso, concretamente en el 26:
http://c.conclase.net/curso/index.php?cap=026

Básicamente, los espacios con nombre permiten declarar múltiples conjuntos de clases, objetos, funciones, etc, y en cada uno de ellos se pueden usar identificadores independientemente de los usados en otros espacios.

La utilidad es limitada, cuando se escriben programas pequeños o sólo participa un programador. Esta característica está pensada, sobre todo, para aplicaciones creadas por equipos de programadores, o cuando se integran en una misma operación varios códigos o librerías diferentes.

Cada programador de un equipo, o cada librería puede declarar todos sus identificadores en un espacio con un nombre diferente. De ese modo se evita la posibilidad de que distintos programadores usen el mismo nombre para un objeto, clase, función o tipo, y resulte imposible enlazarlos todos juntos.

En realidad trabajan como los prefijos telefónicos de país. De este modo, cada país puede usar los mismos números de teléfono, y sólo cuando se quiere hacer una llamada internacional, se añade el prefijo adecuado. Eso también hace que los números que usamos normalmente sean más cortos.

Concretamente, en el espacio con el nombre "std" se incluyen todas las declaraciones de las librerías estándar de C y C++.

Eso responde a la primera pregunta.

Pero hay un detalle importante que hay que tener en cuenta. En C, y en las primeras versiones de los compiladores de C++, los ficheros de cabecera estándar tienen nombres con la extensión ".h". Pero en C++ (y en las últimas versiones del compilador se ha llevado a la práctica), los ficheros de cabecera no tienen extensión. De hecho, ni siquiera tienen que ser un fichero de disco, aunque hasta la fecha lo son. Pueden ser sólo una especie de "directiva" o macro.

En los ficheros con extensión ".h" no se usa el espacio con nombre "std", y lo cierto es que actualmente sólo existen para mantener la compatibilidad con ficheros fuente anteriores, y no deben usarse.

Así que, generalmente, existen dos versiones de cada fichero de cabecera, con extensión ".h" y sin ella. En el caso de librerías estándar C++, la mayor diferencia entre ambos es el uso del espacio con nombre. En el caso de ficheros de cabecera de librerías estándar C, además hay que añadir el prefijo "c" al nombre. Así, existen ficheros como "iostream.h" e "iostream", o, para ficheros C, "stdio.h" y "cstdio".

Creo que eso responde a la segunda pregunta.

DR> Tengo entendido que pueden existir muchas funciones cout distintas (por
DR> ejemplo), en diferentes archivos de encabezado. Para usar una de esas
DR> funciones en específico se tendría que llamar de la siguiente forma:
DR> ¿Clase o Archivo de encabezado?::función();
DR> ( En realidad no sé si sea el archivo de encabezado o la clase lo que se
DR> antepone a los dos puntos. Se supone que en el caso de la salida estándar es
DR> std::cout, pero std no es la clase ... creo.

Lo que se ha de anteponer es el identificador del espacio con nombre, en este caso "std".

Efectivamente, este mecanismo nos permite crear funciones, tipos, clases u objetos con el mismo nombre, en otros espacios.

Por ejemplo, podríamos usar identificadores como "cout" o "printf" para nuestros propios usos, siempre que lo hagamos en otro espacio distinto de "std".

DR> Volviendo a lo que tengo entendido, para utilizar el cout de salida estándar
DR> se utiliza std::cout. Para evitar tener que escribir siempre std::, se
DR> utiliza el "nombre de espacios" std (estándar) y de esta manera sólo
DR> escribimos cout.

No, lo que se usa es la directiva "use namespace <nombre_de_espacio>;"

A partir de ese punto, los identificadores que no vayan precedidos con un nombre de espacio y el operador ::, se buscan en el espacio global y si no se encuentra, en el especificado por la directiva.

Básicamente sirve para ahorrarnos trabajo al escribir el programa.

DR> Pero realmente no encuentro diferencias en hacer:
DR> #include <iostream.h>
DR> >
DR> > int main {
DR> >     ...
DR> >     cout << a;
DR> y
DR> #include <iostream>
DR> > using namespace std;
DR> >
DR> > int main {
DR> >     ....
DR> >     cout << a;

La diferencia es que la primera versión se considera obsoleta, y los compiladores actuales lanzan un aviso cuando se usa.

DR> P.D. Leyendo este mensaje antes de enviarlo, acabo de acordarme que lo de
DR> std es precisamente el namespace. Para otras funciones, ¿cómo puedo saber el
DR> nombre de espacio al que pertenecen?

En general, siembre vas a saber a qué espacio con nombre pertenece cada identificador, sobre todo porque cuando los uses será algo que hagas consciente e intencionadamente.

Si necesitas usar una librería de gráficos, en la que todos los identificadores se han declarado en el espacio con nombre "graf", ese dato será parte de la documentación de la librería, y, o bien activas el nombre del espacio usando la directiva "using namespace", o bien usas el nombre completo en cada ocasión.

Lo mismo si trabajas en un proyecto con otros programadores, sabrás en que espacio fue declarado cada identificador porque la documentación lo debe decir.

En último caso, siembre puedes abrir el fichero de cabecera y ver en que espacio con nombre se declaran sus identificadores.

Hasta pronto.

-- 
Salvador Pozo (Administrador)
mailto:salvador en conclase.net


Más información sobre la lista de distribución Cconclase