Manual C++ Ing Hidalgo
Manual C++ Ing Hidalgo
de
Programación
enC++
1
1. INTRODUCCION
C++ es una mejoría sobre muchas de las características de C, y proporciona capacidades de P.O.O. que
promete mucho para incrementar la productividad, calidad y reutilización del software.
En C++, la unidad de programación es la clase a partir de la cual, los objetos son producidos. Se trata,
pues, de una programación orientada al objeto.
Se pueden especificar entradas/salidas de tipos definidos por el usuario, así como de tipos estándar. Esta
extensibilidad es una de las características más valiosas de este lenguaje de programación.
C++ permite un tratamiento común de entradas/salidas de tipos definidos por usuario. Este tipo de
estado común facilita el desarrollo de software en general y de la reutilización de software en particular.
La salida de flujo puede ser ejecutada mediante el operador de inserción de flujo : <<. Se hace la
homonimia del operador << para extraer elementos de datos de tipos incorporados, para extraer cadenas y
para extraer valores de apuntadores.
Ejemplo:
# include <iostream.h>
main( )
{
cout <<''¡ Bienvenido a C++! \n'';
return 0;
}
Todas las palabras claves de C++ están en minúsculas. En C++, las mayúsculas yminúsculas son
diferentes.
2
A continuación se muestra dos tablas de palabras reservadas en C++ :
C y C++
auto break case char const
continue default do double else
enum extern float for goto
if int long register return
short signed sizeof static struct
switch typedef union unsigned void
volatile while
C++ únicamente
3
2. C++ COMO UN ''C MEJORADO''
2.1. COMENTARIOS Y DECLARACIONES EN C++
C++ permite empezar un comentario con // y usar el resto de la línea para texto del comentario; el fin de la línea
da de manera automática por terminado el comentario. También es aceptable la forma de C : /* */.
En C++, a diferencia de C, las declaraciones pueden ser colocadas en cualquier parte de un enunciado ejecutable,
siempre y cuando las declaraciones antecedan el uso de lo que se está declarando. También, las variables pueden ser
declaradas en la sección de inicialización de una estructura for; dichas variables se mantienen en alcance hasta el
final del bloque en el cual la estructura for está definida.
El alcance de una variable local C++ empieza en su declaración y se extiende hasta la llave derecha de cierre. Las
declaraciones de variables no pueden ser colocadas en la condición de una estructura while, do/while, for o if.
C++ requiere que se declaren todos los parámetros de función en los paréntesis de la definición de función y del
prototipo. Una lista vacía de parámetros se especificaescribiendo void o absolutamente nada en los paréntesis.
4
Ejemplo:
#include <iostream.h>
main( )
{
cout << ''Introduce la longitud del lado de tu cubo: '';
float lado;
cin >> lado;
cout << ''El volumen del cubo de lado ''
<< lado << ''es'' << cubo( lado ) << '\n';
return 0;
}
Debemos usar apuntadores para pasar argumentos que pudieran ser modificados por la función llamada,
y usar referencias a constantes para pasar argumentos extensos, que no serán modificados.
Las variables de referencia deben ser inicializadas en sus declaraciones, y no puedenser reasignadas
como seudónimos a otras variables.
Cuando se regresa un apuntador o una referencia a una variable declarada en la función llamada, la
variable deberá ser declarada static dentro de dicha función.
Las referencias pueden ser usadas como argumentos de funciones y regresar valores.Ejemplo:
Otro uso común para el calificador const es para poder declarar un apuntador constante.
5
Tabla con expresiones de declaración de constantes:
6
1.1. ASIGNACION DINAMICA DE MEMORIA MEDIANTE NEW Y DELETE
En C++, el enunciado
ptr = new typeName;
asigna memoria para un objeto del tipo typeName. El operador new crea automáticamente un objeto del
tamaño apropiado, y regresa un apuntador (ptr)del tipo apropiado. Si mediante new no se puede asignar
memoria, se regresa un apuntador nulo.
El operador delete sólo puede ser utilizado para desasignar memoria ya asignada mediante el operando
new.
Ejemplo:
#include <iostream.h>
float v;
int main( )
{
int v = 7;
::v = 10.5; // Utilizar la variable global v
cout << ''variable local v = '' << v << ''\n'';
cout << ''variable global v = '' << ::v << ''\n'';
return 0;
}
7
1.1. HOMONIMIA DE FUNCIONES
C++ permite que sean definidas varias funciones del mismo nombre (sobrecarga de funciones), siempre
que estos nombres indiquen distintos conjuntos de parámetros. Esta capacidad se llama homonimia de
funciones. La homonimia de la función se utiliza por lo común para crear varias funciones del mismo
nombre, que ejecuten tareas similares, sobre tipos de datos distintos.
Ejemplo:
#include <stdio.h>
int max( int a, int b )
{
if ( a > b ) return a;
return b;
}
char *max( char *a, char *b )
{
if ( strcmp (a,b) > 0 ) return a;
return b;
}
int main( )
{
printf ( ''max( 19, 69 ) = %d\n'', max( 19, 69 ) );
printf ( ''max( abc,def ) = %s\n'', max( ''abc'',''def'' ) );
return 0;
}
El programa del ejemplo define dos funciones que difieren en su lista de parámetros, de ahí que defina
dos funciones distintas.
Las referencias se pueden usar para proveer una función con un alias de un argumento real de llamada
de función. Esto permite cambiar el valor del argumento de llamada de función tal como se conoce de
otros lenguajes de programación de llamada-por- referencia:
Las plantillas de función proporcionan, como las macros, una solución compacta, pero permiten
verificación completa de tipo.
Todas las definiciones de plantillas de función empiezan con la palabra reservada template ( ver
apdo.4.8, pág. 31 ), seguida por una lista de parámetros formales a la plantilla de función encerrados en
corchetes angulares ( < >). Cada parámetro formal es precedido por la palabra reservada class. A
continuación se coloca la definición de función y se define como cualquier otra función.
El nombre de la clase (una vez definida) puede ser utilizado para declarar objetos de dicha clase.
Ejemplo:
La definición de una clase comienza con la palabra reservada class . El cuerpo de la definición de clase
se delimita mediante llaves. La definición de clase termina con un punto y coma. En el cuerpo de la
definición existen partes nuevas: la etiqueta public: y private: se conocen como especificadores de
acceso de miembro. Cualquier miembro de datos o función miembro declarado después del especificador
de acceso de miembro public: (y antes del siguiente especificador de acceso de miembro) es
accesible, sie mpre que el programa tenga acceso a un objeto de la clase. Cualquier miembro de datos o
función miembro declarada después del especificador de acceso de miembro private: (y hasta el siguiente
especificador de acceso de miembro) sólo es accesible a las funciones miembro de la clase.
Estos especificadores pueden aparecer varias veces en una definición de clase. Por defecto, los
elementos de las clases son privados ( private: ).
Por lo regular, los miembros de datos aparecen listados en la porción private: de una clase, y
normalmente, las funciones de miembro aparecen listadas en la porción public:, aunque puede darse el
caso contrario.
Los miembros de datos de una clase no pueden ser inicializados donde son declarados en el cuerpo de la
9
clase. Deberán ser inicializados por el constructor de la clase, o las funciones ''set'' les podrán asignar
valores.
La función con el mismo nombre que la clase, pero precedido por un carácter tilde (~ ) se llama el
destructor de dicha clase.
Cuando una función miembro se define por fuera de la definición de clase, el nombre de función es
antecedido por el nombre de la clase y por el operador de resolución de alcance binario (::). Dicha
función miembro queda dentro del alcance de la clase.
Ejemplo:
El objeto apunto puede usar estos métodos para establecer y para obtener informaciónsobre sí mismo:
Punto apunto;
apunto.setX(1); // Inicialización.
apunto.setY(1);
//
// x es necesaria a partir de aquí, de modo que la definimos aquí y la
// inicializamos con el valor de la coordenada _x de apunto.
//
int x = apunto.getX( );
Dentro del alcance de clase, los miembros de clase son accesibles por todas las funciones miembro de
dicha clase y pueden ser referenciados sólo por su nombre. Fuera del alcance de una clase, los miembros
de clase se referencian, ya sea a través del nombre del objeto, una referencia a un objeto, o un apuntador a
un objeto.
10
1.2. COMO CONTROLAR EL ACCESO A MIEMBROS
Se puede tener acceso a los miembros de clase privado sólo por miembros (y amigos) de dicha clase. Se
puede tener acceso a los miembros públicos de una clase mediante cualquier función del programa.
El cliente de una clase puede ser una función miembro de otra clase, o puede ser una función global.
Los miembros de clase públicos presentan una vista de los servicios que proporciona laclase.
El acceso a los datos privados de una clase puede ser controlado con cuidado mediante el uso de las
funciones miembro conocidas como funciones de acceso. Si una clase desea permitir que los clientes
lean datos privados, la clase puede proporcionar una función ''get''. Para permitir que los clientes
modifiquen datos privados, la clase puede proveer una función ''set''.
Ejemplo:
#include <iostream>
// Definición de la clase Cfecha
class Cfecha
{
public:
// Constructor ( véase apdo. siguiente)
Cfecha( int dd = 1, int mm = 1, int aa = 1980 );
// Funciones de acceso
void get_fecha( int &, int &, int & );
void set_fecha( int, int, int );
private:
int dia, mes, anyo; // Datos miembro
};
// Constructor
Cfecha::Cfecha( int dd, int mm, int aa )
{
set_fecha( dd, mm, aa );
}
// Obtener una fecha
void Cfecha::get_fecha( int &dd, int &mm, int &aa )
{
dd = dia, mm = mes, aa = anyo;
}
11
1.3. COMO INICIALIZAR OBJETOS DE CLASE : CONSTRUCTORES
Los constructores son métodos que se usan para inicializar un objeto al momento de su definición o para
asignar almacenamiento en memoria. Cuando se declara un objeto de una clase, se pueden dar
inicializadores en paréntesis a la derecha del nombre del objeto y antes del punto y coma. Estos
inicializadores son pasados como argumentos al constructor de la clase.
Si para una clase no se define ningún constructor, el compilador creará un constructor por omisión.
Dicho constructor no ejecutará ninguna inicialización.
Debemos incluir siempre un constructor que ejecute la inicialización adecuada para su clase.
Ejemplo:
class Punto
{
int _x, _y;
public :
Punto( )
{
_x = _y = 0;
}
void SetX( const int val );
void SetY( const int val );
int getX { return _x; }
int getY { return _y; }
};
class Punto
{
int _x, _y;
public:
Punto()
{
_x = _y = 0;
}
12
// Continuamos con el ejemplo:
Punto (const int x, const int y)
{
_x = x; // Para poder inicializar un punto en
_y = y; // otras coordenadas que no sean (0,0).
}
void setX (const int val);
void setY (const int val);
int getX() { return _x;}
int getY() { return _y;}
};
1.4. DESTRUCTORES
Un destructor de clase es llamado automáticamente cuando un objeto de una clase se sale de alcance:
debemos asegurarnos de que la memoria asignada sea liberada.
Este método especial llamado destructor es llamado una vez por cada objeto en el momento de su
destrucción.
Un destructor no recibe parámetros ni regresa ningún valor. Una clase sólo puede tener un destructor: la
homonimia de destructores no está permitida.
La destrucción de los objetos tiene lugar cuando el objeto abandona su ámbito de definición o es
explícitamente destruido. Esto último sucede cuando nosotros dinámicamente asignamos un objeto y lo
liberamos cuando ya no nos es necesario.
Los destructores se declaran con el nombre de la clase prefijado con una tilde ( ~ ):
class Punto
{
int _x, _y;
public:
Punto()
{
_x = _y = 0;
}
13
// Continuamos con el ejemplo:
Punto (const int x, const int y)
{
_x = xval;
_y = yval;
}
Punto (const Punto &desde)
{
_x = desde._x;
_y = desde._y;
}
Punto() { /* ¡Nada que hacer! */}
void setX(const int val);
void setY(const int val);
int getX() {return _x;}
int getY() {return _y;}
};
2. CLASES
2.1. OBJETOS CONSTANTES Y FUNCIONES MIEMBRO CONST
La palabra reservada const indica que un objeto no es modificable. Para objetos const no se permiten
llamadas de función miembro. Se pueden declarar funciones miembro const : sólo éstas pueden operar
sobre objetos const; estas funciones no pueden modificar el objeto.
Una función es definida como const tanto en su declaración como en su definición, insertando la
palabra reservada const después de la lista de parámetros de la función, y, en el caso de la definición de
función, antes de la llave izquierda que inicia el cuerpo de la función.
Ejemplo:
14
const Cfecha cumpleanyos;
cumpleanyos.ok_fecha( );
class Cfecha
{
public:
// Funciones miembro de la clase
//...
int ok_fecha( ) const;
//...
};
int Cfecha::ok_fecha( ) const
{
// Cuerpo de la función
}
Si una función miembro const se define fuera de la definición de la clase, tanto la declaración como la
definición de la función miembro deberán incluir const.
Una función miembro const puede ser homónima en una versión no const.
15
2.2. COMPOSICION: CLASES COMO MIEMBROS DE OTRAS CLASES
Una clase puede tener otras clases como miembros.
Cuando un objeto entra en alcance, su constructor es llamado automáticamente, por lo que es preciso
especificar cómo se pasan argumentos a constructores de objetos miembro. Se construyen los objetos
miembro antes de que los objetos de clase que los incluyen sean construidos.
Para declarar una función como un friend de una clase, en la definición de clase hay que preceder el
prototipo de función con la palabra reservada friend.
Las declaraciones de amistad pueden ser colocadas en cualquier parte de la definición de clase.
Es posible especificar funciones homónimas como amigos de una clase. Cada función homónima que se
desea como un amigo, debe ser declarada en forma explícita en la definición de clase como amigo de la
clase.
Ejemplo:
class Complejo
{
...
public:
...
friend Complejo operator +
(
const Complejo &,
const Complejo &
);
}
Complejo operator +(const Complejo &op1, const Complejo &op2)
{
double real = op1._real + op2._real,
imag = op1._imag + op2._imag;
16
No se deben usar amigos muy seguido debido a que rompen con el principio de aislamiento de datos en
sus fundamentos. Si los usamos de forma muy seguida, es señal de que tenemos que modificar nuestra
gráfica de herencia.
El apuntador this es utilizado de manera implícita para referenciar tanto los miembros de datos como las
funciones miembro de un objeto. El tipo de este apuntador this depende del tipo del objeto y de si es
declarada const la función miembro en la cual this es utilizado.
Un uso del apuntador this es impedir que un objeto sea asignado a sí mismo.
Ejemplo:
fecha1.set_fecha( );
void Cfecha::set_fecha( )
{
cout << ''día, ## : ''; cin >> this->dia;
cout << ''mes, ## : ''; cin >> this->mes;
cout << ''año, #### : ''; cin >> this->anyo;
}
17
2.5. ASIGNACION DINAMICA DE MEMORIA MEDIANTE NEW Y DELETE
Los operadores new y delete ofrecen una mejor forma de efectuar la asignación dinámica de memoria,
que mediante las llamadas de función malloc y free de C.
El operador new crea en forma automática un objeto del tamaño apropiado, llama el constructor para el
objeto (si hay uno disponible) y regresa un apuntador del tipo correcto. Si new no puede encontrar
espacio, regresa un apuntador 0.
char *ptr;
ptr = new char[longitud];
delete ptr;
Estos miembros de datos estáticos tienen alcance de clase. Pueden ser públicos, privados o protegidos.
Una función miembro puede ser declarada static si no tiene acceso a miembros de clase no estáticos. A
diferencia de las funciones miembro no estáticas, una función miembro estática no tiene apuntador this.
Los miembros estáticos de una clase son accesibles a través de un objeto de dicha clase, o pueden ser
accesibles a través del nombre de la clase mediante el uso del operador de resolución de alcance.
Asociamos iteradores con la clase de colección. Un iterador es un objeto que regresa el siguiente
elemento de una colección. Una clase contenedor puede tener varios iteradores operando sobre ella
simultáneamente.
18
El recorrido de una estructura de datos es implementado usando iteradores. Estos garantizan la visita a
cada ítem de su estructura de datos asociada en un orden bien definido. Deben proveer al menos las
siguientes propiedades:
1. Elemento actual. El iterador visita los elementos de datos uno a la vez. El elemento que se visita
actualmente es llamado el ''elemento actual''.
2. Función sucesor. La ejecución del paso al siguiente elemento de datos depende dela estrategia de
recorrido implementada por el iterador. La función sucesor se usa para regresar el elemento que
será visitado enseguida: regresa el sucesor del elemento actual.
3. Condición de terminación. El iterador debe proveer un mecanismo que chequee si se han visitado
todos los elementos, o si falta alguno por visitar.
en la línea que antecede a la definición de clase. Puede existir más de un tipo parametrizado. Si es así,
estarán separados por comas y cada tipo estará precedido por la palabra reservada class. ( Ver apdo. 2.11.,
pág. 20).
Luego, con la palabra clave template se inician todas las declaraciones de plantillas. Los argumentos de
una plantilla se encierran en corchetes angulares.
Ejemplo:
19
Una clase plantilla se produce especificando el tipo de la clase que sigue al nombre de laclase:
NombreClase<tipo> NombreObjeto;
Ejemplo :
Lista<int> listaDeEnteros
El único fin de una clase abstracta es proporcionar una clase base apropiada, a partir de la cual las clases
pueden heredar interfaz y/o puesta en práctica. Las clases a partir de las cuales los objetos se pueden
producir, se conocen como clases concretas.
Se definen igual que las clases ordinarias. Sin embargo, algunos de sus métodos están designados para
ser definidos necesariamente por sus subclases. Sólo mencionamos su signature (nombre del método más
sus argumentos) incluyendo el tipo que regresa, pero no una definición. Se podría decir que omitimos el
cuerpo del método. Esto se expresa añadiendo ''=0'' después de las ''signatures'' de los métodos:
class ObjetoDesplegable
{
...
public:
...
virtual void print( ) = 0;
};
Estas declaraciones de métodos son también llamadas métodos puros. También deben ser declarados
virtuales, debido a que sólo queremos usar objetos de clases derivadas. Las clases que definen métodos
puros son llamadas clases abstractas.
20
3. HOMONIMIA DE OPERADORES
Se hace la homonimia de operadores escribiendo una definición de función (con encabezado y cuerpo)
como se haría normalmente, excepto que ahora el nombre de la función se convierte en la palabra clave
operator, seguida por el símbolo correspondiente al operador homónimo:
Para utilizar un operador sobre objetos de clase, dicho operador deberá ser un homónimo con dos
excepciones. El operador de asignación ( = ) puede ser utilizado sin homónimo con cualquier clase. El
operador de dirección ( & ) también puede ser utilizado sin homonimia con objetos de cualquier clase.
21
No es posible modificar el número de operandos que toma un operador. Tampoco se pueden crear
operadores nuevos; sólo se puede hacer la homonimia de operadores existentes.
La homonimia de operador funciona sólo con objetos de tipos definidos por el usuario o por una
combinación de un objeto de tipo definido por el usuario y un objeto de tipo incorporado.
Los operadores de entrada y de salida homónimos deben ser declarados como amigo, si han de tener
acceso directo a los miembros de clase no públicos.
Class Complejo
{
...
public :
...
Complejo operator + ( const Complejo &op)
{
double real = _real + op._real,
imag = _imag + op._imag;
return (Complejo ( real, imag));
}
...
};
22
En este caso, se ha hecho del + un miembro de la clase Complejo. Así, una expresiónde la forma:
c = a + b;
es traducida a una llamada a método :
c = a.operator +(b);
Así, el operador binario + sólo necesita un argumento. El primer argumento es provisto implícitamente
por el objeto invocante (en este caso a).
Para evitar que un objeto de clase sea asignado a otro, debemos definir el operador de asignación como
miembro privado de la clase.
Un operador de conversión ( operador de conversión explícita cast ) puede ser utilizado para convertir
un objeto de una clase en un objeto de otra clase o en un objeto de un tipo incorporado. Este operador no
puede ser una función amigo; debe ser una función miembro no estática.
nombre-de-tipo(expresión)
Ejemplos:
sqrt (double(n+2))
23
4. HERENCIA
La herencia es una forma de reutilización del software, en la cual se crean clases nuevas a partir de
clases existentes, mediante la absorción de sus atributos y comportamientos, y embelleciendo éstos con
las capacidades que las clases nuevas requieren.
Al crear una clase nueva, en vez de escribir en su totalidad miembros de datos y funciones miembro
nuevos, el programador puede determinar que la clase nueva debe heredar los miembros de datos y las
funciones miembro provenientes de una clase base ya definida. La clase nueva se conoce como clase
derivada.
La herencia forma estructuras jerárquicas de apariencia arborescente. Una clase base existe en una
relación jerárquica con sus clases derivadas.
Mediante la herencia única, una clase es derivada de una única clase base. Con la
herencia múltiple una clase derivada hereda de múltiples clases base.
En C++, ''hereda de'' se reemplaza por dos puntos ( : ). Luego, la sintaxis para escribir una clase
derivada es:
Ejemplo:
24
4.1. TIPOS DE HERENCIA
C++ distingue dos tipos de herencia : pública y privada. Por defecto, las clases se derivan unas de
otras en forma privada. Si queremos herencia pública, debemos decírselo explícitamente al compilador.
El tipo de herencia influye sobre los privilegios de acceso a elementos de las diversas superclases.
Los miembros públicos de una clase base son accesibles a todas las funciones en el programa. Los
miembros privados de clase base son accesibles sólo para las funciones miembro y los amigos de la clase
base.
El tipo protected se usa para elementos que deberían ser usados directamente en las subclases, pero que
no deberían estar accesibles desde fuera. Luego, el acceso protegido sirve como nivel intermedio de
protección entre el acceso público y el privado. Los miembros protegidos de clase base son accesibles
sólo por miembros y amigos de la clase base, y por miembros y amigos de las clases derivadas.
Los miembros de clases derivadas pueden hacer referencia a miembros públicos y protegidos de la
clase base sólo utilizando los nombres de los miembros.
Al derivar una clase a partir de una clase base pública, los miembros públicos de la base se convierten
en miembros públicos de la clase derivada, y los miembros protegidos de la clase base se convierten en
miembros protegidos de la clase derivada. Los miembros privados de una clase base nunca son accesibles
en forma directa desde una clase derivada.
Al derivar una clase a partir de una clase base protegida, los miembros públicos y protegidos de la clase
base se convierten en miembros protegidos de la clase derivada.
Cuando se deriva una clase a partir de una clase base privada, los miembros públicos y protegidos de la
clase base se convierten en miembros privados de la clase derivada.
private si no no
25
4.3. CONSTRUCCION Y DESTRUCCION
En general, anterior a la ejecución del cuerpo particular del constructor, los constructores de cada
superclase son llamados para inicializar su parte del objeto creado. Así, al constructor de clase derivada
siempre llamará primero al constructor de su clase base, a fin de crear y de inicializar los miembros de la
clase base de la clase derivada.
Podemos especificar los constructores deseados después de un signo de dos puntos (:).Ejemplo:
Si hay más superclases, proveemos sus llamadas a constructor como una lista separadapor comas. Este
mecanismo se usa también para crear objetos contenidos.
La inicialización dinámica puede ser usada con tipos de datos integrados. Por ejemplo:
Los destructores serán llamados en orden inverso a las llamadas de constructor, por lo que un destructor
de clase derivada será llamado antes del destructor de su clase base ( o superclase). ( Ver apdo. 3.5., pág.
25 ).
Sintaxis:
class tipo_base_derivada: (public/private/protected)tipo_clase_base1,
(public/private/protected)tipo_clase_base2 { };
26
5. POLIMORFISMO
Es la capacidad de objetos de clases distintas, relacionados mediante la herencia, a responder de forma
diferente a una misma llamada de función miembro. En C++, el polimorfismo se realiza por uno de los
métodos siguientes: sobrecarga de operadores o funciones virtuales.
Podemos declarar que los métodos de las clases sean virtual con el fin de forzar que su evaluación se
base en el contenido de los objetos más que en su tipo. Con el uso de esta palabra clave, una función
puede estar definida en una clase base y en su clase derivada bajo el mismo nombre. La función no
deberá ser declarada virtual más que enla clase base:
class ObjetoDesplegable
{
public:
virtual void print( );
};
La clase ObjetoDesplegable define un método print( ), el cual es virtual. De esta clasepodemos derivar
otras clases:
Nuevamente, print( ) es un método virtual debido a que hereda esta propiedad de ObjetoDesplegable. La
función display( ), que es capaz de dibujar cualquier tipo de objeto desplegable, puede por tanto ser
definida como:
Cuando se usan métodos virtuales, el destructor de la clase correspondiente debe ser declarado también
virtual cuando se usan apuntadores a subclases (virtuales) cuando llega el momento de destruirlas. Debido
a que el apuntador está declarado como superclase, su destructor normalmente sería llamado.
27
6. PLANTILLAS PARA LOS NODOS
El nodo es el bloque básico de construcción de una lista. Un nodo no tiene nada másque un apuntador a
otro nodo.
class Nodo
{
Nodo *_derecha; // Asumimos que este nodo vecino siempre
// está del lado derecho.
public :
Nodo ( Nodo *derecha = NULL) : _derecha ( derecha) { }
Nodo ( const Nodo &val) : _derecha ( val._derecha) { }
// Const justo antes del cuerpo del método: declara constante al método
// en lo que respecta a los elementos del objeto invocante. Sólo se puede
// usar este mecanismo en declaraciones de métodos o definiciones.
Cuando usamos un const justo antes del cuerpo del método (como ocurre en derecha()), const declara al
método constante en lo que respecta a los elementos del objeto invocante. Sólo está permitido usar este
mecanismo en declaraciones de métodos o definiciones, respectivamente.
Este tipo de modificador const también se usa para checar sobrecarga. Así:
28
class Arboles
{
...
int arboles( ) const;
int arboles( );
};
En el ejemplo anterior, el modificador const declara dos métodos distintos. El primero se usa en
contextos constantes y el segundo en contextos variables.
Las aplicaciones reales requieren que los nodos lleven datos. Esto significa especializar los nodos. Los
datos pueden ser de cualquier tipo; usamos la construcciónde plant illa:
{
T _data;
public :
DatoNodo ( const T dato, DatoNodo *derecha = NULL) :
Nodo ( derecha ), _dato ( dato) {}
DatoNodo ( const DatoNodo &val) :
Nodo ( val), _dato ( val._dato) {}
29
// Continuamos :
7. COMPILAMOS UN PROGRAMA
• Descripciones de interface, y
• archivos de implementación.
Para distinguir estos tipos, se usa un conjunto de sufijos cuando se compilanprogramas de C y C++ :
.c Implementación de archivos de C.
30
7.1. PASOS DE LA COMPILACION
El proceso de compilación toma los archivos .cc, los preprocesa y los traduce en
archivos objeto.
.cc
Linker librerías
En los ordenadores Alpha OSF/1 de la U.C.M., para compilar y linkar ( enlazar ) unprograma basta con
hacer:
cxx nombre_del_programa.cxx
man c
31
FLUJO DE ENTRADA/SALIDA DE C++
Los usuarios pueden especificar entradas/salidas de tipos definidos por usuario, así como de tipos
estándar.
Además del operador <<, la clase ostream proporciona las funciones put para visualizar caracteres, y
write para visualizar cadenas:
ENCABEZADO DESCRIPCION
iomanip.h Contiene información útil para llevar a cabo
entradas/salidas con formato, mediante manipuladores de
flujo parametrizados.
La función miembro get con un argumento de carácter, introduce el carácter siguientedel flujo de
entrada.
32
1.1. ENTRADAS/SALIDAS SIN FORMATO UTILIZANDO READ, GCOUNT YWRITE
Se lleva a cabo entradas/salidas sin formato mediante las funciones miembro read y write. Cada una de
estas funciones introduce o extrae, respectivamente, un número designado de caracteres de o desde un
arreglo de caracteres existente en memoria.
MANIPULADOR DESCRIPCION
33
34
35
36
37
38
39
40
41