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 279 — #317<br />

✐<br />

10.1. Los elem<strong>en</strong>tos estáticos de C<br />

Para mostrar qué constructores y qué destructores serán llamados, sólo se invoca<br />

a f(). La salida del programa será la sigui<strong>en</strong>te:<br />

Obj::Obj() for a<br />

inside main()<br />

Obj::Obj() for b<br />

leaving main()<br />

Obj::~Obj() for b<br />

Obj::~Obj() for a<br />

El constructor para a se invoca antes de <strong>en</strong>trar <strong>en</strong> main() y el constructor de b se<br />

invoca sólo porque existe una llamada a f(). Cuando se sale de main(), se invoca<br />

a los destructores de los objetos que han sido construidos <strong>en</strong> ord<strong>en</strong> inverso al de su<br />

construcción. Esto significa que si llama a g(), el ord<strong>en</strong> <strong>en</strong> el que los destructores<br />

para b y c son invocados dep<strong>en</strong>de de si se llamó primero a f() o a g().<br />

Nótese que el objeto out de tipo ofstream, utilizado <strong>en</strong> la gestión de ficheros,<br />

también es un objeto estático (puesto que está definido fuera de cualquier función,<br />

reside <strong>en</strong> el área de almac<strong>en</strong>ami<strong>en</strong>to estático). Es importante remarcar que su definición<br />

(a difer<strong>en</strong>cia de una declaración tipo extern) aparece al principio del fichero,<br />

antes de cualquier posible uso de out. De lo contrario estaríamos utilizando un objeto<br />

antes de que estuviese adecuadam<strong>en</strong>te inicializado.<br />

En <strong>C++</strong>, el constructor de un objeto estático global se invoca antes de <strong>en</strong>trar <strong>en</strong><br />

main(), de forma que ya dispone de una forma simple y portable de ejecutar código<br />

antes de <strong>en</strong>trar <strong>en</strong> main(), así como ejecutar código después de salir de main(). En<br />

C, eso siempre implicaba revolver el código <strong>en</strong>samblador de arranque del compilador<br />

utilizado.<br />

10.1.2. Control del <strong>en</strong>lazado<br />

G<strong>en</strong>eralm<strong>en</strong>te, cualquier nombre d<strong>en</strong>tro del ámbito del fichero (es decir, no incluido<br />

d<strong>en</strong>tro de una clase o de una función) es visible para todas las unidades de<br />

traducción del programa. Esto suele llamarse <strong>en</strong>lazado externo porque durante el<br />

<strong>en</strong>lazado ese nombre es visible desde cualquier sitio, desde el exterior de esa unidad<br />

de traducción. Las variables globales y las funciones ordinarias ti<strong>en</strong><strong>en</strong> <strong>en</strong>lazado<br />

externo.<br />

Hay veces <strong>en</strong> las que convi<strong>en</strong>e limitar la visibilidad de un nombre. Puede que<br />

desee t<strong>en</strong>er una variable con visibilidad a nivel de fichero de forma que todas las<br />

funciones de ese fichero puedan utilizarla, pero quizá no desee que funciones externas<br />

a ese fichero t<strong>en</strong>gan acceso a esa variable, o que de forma inadvertida, cause<br />

solapes de nombres con id<strong>en</strong>tificadores externos a ese fichero.<br />

Un objeto o nombre de función, con visibilidad d<strong>en</strong>tro del fichero <strong>en</strong> que se <strong>en</strong>cu<strong>en</strong>tra,<br />

que es explícitam<strong>en</strong>te declarado como static es local a su unidad de traducción<br />

(<strong>en</strong> términos de este libro, el fichero cpp donde se lleva a cabo la declaración).<br />

Este nombre ti<strong>en</strong>e <strong>en</strong>lace interno. Esto significa que puede usar el mismo nombre<br />

<strong>en</strong> otras unidades de traducción sin confusión <strong>en</strong>tre ellos.<br />

Una v<strong>en</strong>taja del <strong>en</strong>lace interno es que el nombre puede situarse <strong>en</strong> un fichero de<br />

cabecera sin t<strong>en</strong>er que preocuparse de si habrá o no un choque de nombres durante el<br />

<strong>en</strong>lazado. Los nombres que aparec<strong>en</strong> usualm<strong>en</strong>te <strong>en</strong> los archivos de cabecera, como<br />

definiciones const y funciones inline, ti<strong>en</strong><strong>en</strong> por defecto <strong>en</strong>lazado interno. (De<br />

todas formas, const ti<strong>en</strong>e por defecto <strong>en</strong>lazado interno sólo <strong>en</strong> <strong>C++</strong>; <strong>en</strong> C ti<strong>en</strong>e<br />

<strong>en</strong>lazado externo). Nótese que el <strong>en</strong>lazado se refiere sólo a elem<strong>en</strong>tos que ti<strong>en</strong><strong>en</strong><br />

direcciones <strong>en</strong> tiempo de <strong>en</strong>lazado / carga. Por tanto, las declaraciones de clases y<br />

279<br />

✐<br />

✐<br />

✐<br />

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

Saved successfully!

Ooh no, something went wrong!