You are on page 1of 24

Repblica Bolivariana de Venezuela

Ministerio del Poder Popular para la Defensa


Universidad Nacional Experimental Politcnica de la
Fuerza Armada
Ncleo Apure
O4-IST-D01

Sintaxis y lista C++


Prof.
Ing. Anbal Aguilar

Integrantes:
Aguirre Miguel
Cedeo Wilna
Hidalgo Solmaira
Julia Figueroa
Orozco Iris
Torres Garykel

Unefa, diciembre de 2014

SINTAXIS
La palabra sintaxis proviene del trmino en latn syntaxis, que a su vez
deriva de un vocablo griego que se traduce al espaol como coordinar. Se trata
de la rama de la gramtica que ofrece pautas creadas para saber cmo unir y
relacionar palabras a fin de elaborar oraciones y expresar conceptos de modo
coherente. En la informtica, la sintaxis se entiende como el grupo de normas que
marcan las secuencias correctas de los elementos propios de un lenguaje de
programacin.
LISTAS
Las listas al igual que las pilas y las colas, son una estructura de datos de
tipo lineal diferencindose de las anteriores en el hecho de que pueden las
inserciones y eliminaciones se en cualquier parte de la lista. Esto hace que tengan
mayor aplicabilidad en el entorno real. Se abordan los temas relacionados con los
conceptos bsicos de las listas, as como tipos de listas y las operaciones que se
pueden realizar con las listas, todo conjugado en programas de aplicacin,
implementados con apuntadores.
Se hace uso de un men de opciones para cada programa y funciones para la
insercin, visualizacin, eliminacin y bsqueda de nodos en la lista. Al igual que
en los anteriores captulos, cada uno de los programas aqu presentados, estn
previamente compilados y depurados de tal manera que se mustra la salida en
pantalla de cada uno. Lo anterior garantiza al estudiante que puede guiarse en el
cdigo fuente para hacerle modificaciones y proponer soluciones a entornos
reales.
CONCEPTOS BSICOS DE LISTAS
Una lista enlazada es una coleccin o secuencia de elementos del mismo
tipo dispuestos uno detrs de otro, en el que cada elemento se liga al siguiente
elemento por un enlace que no es ms que un puntero previamente definido.
Las listas segn su estructura se han dividido en cuatro grandes categoras:
1.- Listas Simplemente enlazadas
2.- Listas Doblemente enlazadas
3.- Listas Circular simplemente enlazada
4.- Lista circular doblemente enlazada
LISTA SIMPLEMENTE ENLAZADA
Entre las listas simplemente enlazadas se encuentra un tipo de lista con
poca aplicabilidad llamada Lista contigua:
LISTA CONTIGUA
Es un tipo especial de lista lineal, la cual se compone de un conjunto de
elementos de un tipo dado que se encuentran ordenados y pueden variar en
nmero. Esta es una definicin general, que incluye los ficheros y vectores.
Las entradas de una gua o directorio telefnico, por ejemplo, estn en lneas
sucesivas, excepto en las partes superior e inferior de cada columna. Una lista
lineal se almacena en la memoria principal de una computadora en posiciones

sucesivas de memoria; cuando se almacenan en cinta magntica, los elementos


sucesivos se presentan en sucesin en la cinta. Esta asignacin de memoria se
denomina almacenamiento secuencial. Posteriormente, se ver que existe otro
tipo de almacenamiento denominado encadenado o enlazado. Una lista lineal se
almacena en la memoria de la computadora en posiciones sucesivas o adyacentes
y se procesa como un arreglo unidimensional. En este caso, el acceso a cualquier
elemento de la lista es fcil; sin embargo, la insercin o borrado requiere un
desplazamiento de lugar de los elementos que le siguen y en consecuencia el
diseo de un algoritmo especfico.
Para permitir operaciones con las listas como arreglos se deben
dimensionar stos con tamao suficiente para que contengan todos los posibles
elementos de la lista.
La insercin o eliminacin de un elemento, excepto en la cabecera o final de la
lista, necesita una traslacin de un parte de los elementos de la misma: la que
precede o sigue a la posicin del elemento modificado.
Las operaciones directas de aadir y eliminar se efectan nicamente en los
extremos de la lista. Esta limitacin es una de las razones por las que esta
estructura es poco utilizada.
OPERACIONES CON LISTAS CONTIGUAS
Las operaciones que se pueden realizar con listas lineales contiguas son:
Insertar, eliminar o localizar un elemento
Determinar el tamao - nmero de elementos - de la lista.
Recorrer la lista para localizar un determinado elemento.
Clasificar los elementos de la lista en orden ascendente o descendente.
Unir dos o ms listas en una sola.
Dividir una lista en varias sublistas.
Copiar la lista.
Borrar la lista.
Representacin grfica de una lista contigua

LISTAS ENLAZADAS
Las listas enlazadas o de almacenamiento enlazado son mucho ms
flexibles y potentes, su uso es mucho ms amplio comparado con la lista contigua.
Una lista enlazada o encadenada es un conjunto de elementos del mismo tipo en
los que cada elemento contiene la posicin o direccin del siguiente elemento de
la lista. Cada elemento de la lista enlazada debe tener al menos dos campos: un
campo que tiene el valor del elemento y un campo (enlace, link) que contiene la

posicin del siguiente elemento, es decir, su conexin, enlace o encadenamiento.


Los elementos de una lista son enlazados por medio de los campos enlaces.
Una lista enlazada sin ningn elemento se llama lista vaca.
Su puntero inicial o de cabecera tiene el valor nulo, es decir apunta a NULL.
*puntero NULL;
UNA LISTA ENLAZADA SE DEFINE POR:
El tipo de sus elementos: el campo de informacin donde se almacenan
los datos y el campo de enlace apunta al siguiente elemento lo define un
puntero.
Un puntero de cabecera que permite acceder al primer elemento de la
lista.
Un medio para detectar el ltimo elemento de la lista: puntero nulo (NULL).
Representacin Grfica De Listas Enlazadas

OPERACIONES CON LAS LISTAS ENLAZADAS


Generalmente las operaciones bsicas que se pueden realizar en una lista
enlazada son las siguientes:
OPERACIN DE RECORRIDO:
Esta operacin consiste en visitar cada uno de los elementos que forman la
lista. Para ello se comienza con el primer elemento, se toma el valor del campo
enlace para avanzar al segundo elemento, el campo enlace de este elemento dar
la direccin del tercer elemento y as sucesivamente hasta que la informacin del
campo enlace sea NULL, lo que indica que el recorrido lleg a su final.
OPERACIN DE INSERCIN:
Esta operacin consiste en agregar un nuevo elemento a la lista. Se pueden
considerar tres casos especiales:
Insertar un elemento al inicio de la lista.
Insertar un elemento antes o despus de un determinado elemento o nodo
de la lista.
Insertar un elemento al final de la lista.
OPERACIN DE BSQUEDA:

Esta operacin consiste en visitar cada uno de los elementos, tomando al


campo enlace como puntero al siguiente elemento a visitar en la lista.

OPERACIN DE BORRADO:
La operacin de borrado consiste en eliminar un elemento de la lista,
considerando que se debe redefinir los enlaces involucrados en la operacin. Se
pueden presentar cuatro casos bsicos:
Eliminar el primer elemento de la lista.
Eliminar el ltimo elemento de la lista.
Eliminar de la lista un elemento especfico, es decir, que tenga cierta
informacin.
Eliminar de la lista el elemento anterior o posterior al elemento que tiene
cierta informacin.
IMPLEMENTACIN DE UNA LISTA ENLAZADA CON PUNTEROS
El siguiente programa se plantea como ejemplo gua para implementar una
lista simplemente enlazada con punteros, para gestionar nmeros enteros,
ingresados por teclado con funciones de crear, insertar, eliminar, recorrer y buscar.
Las eliminaciones y la bsqueda, se realizan en cualquier lugar de la lista.
Progra29.cpp
#include <iostream.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
struct lista
{
int dato;
struct lista *sig;
};
void crear(struct lista **);
void insertar(struct lista **, int);
void eliminar(struct lista **, int);
void recorrer(struct lista **);
int buscar(struct lista **, int);
int main()
{
clrscr();
struct lista *entero;
int dato;
crear(&entero);
cout<<"OPERACIONES CON LA LISTA ENLAZADA\n\n ";
cout<<"Para finalizar la insercion Ingrese el cero\n\n ";
cout<<"Ingrese un numero: ";

cin>>dato;
while(dato != 0)
{
insertar(&entero, dato);
cout<<"Ingrese un numero: ";
cin>>dato;
}
cout<<"\n \n ELEMENTOS DE LA LISTA \n\n";
recorrer(&entero);
cout<<"\n \n Ingrese el numero a eliminar: ";
cin>>dato;
eliminar(&entero, dato);
recorrer(&entero);
cout<<"\n \n Ingrese el numero a buscar: ";
cin>>dato;
if(buscar(&entero,dato) == 1)
cout<<"\n El numero "<<<" fue encontrado\n";
else
cout<<"Enl numero no existe "<
getchar();
return 0;
}
// funciones de listas simplemente enlazadas
void crear(struct lista **entero)
{
*entero = NULL;
}
void insertar(struct lista **entero, int dato)
{
struct lista *auxiliar, *puntero, *anterior;
auxiliar = new lista;
if(!auxiliar)
{
cout<<"error:memoria insuficiente"<
exit(1);
}
auxiliar->dato = dato;
anterior = NULL;
puntero = *entero; //puntero es el puntero auxiliar que recorre la lista
while((puntero != NULL) && (puntero->dato < dato))
{
anterior = puntero;
puntero = puntero->sig;
}
if(anterior == NULL)
{
auxiliar->sig = *entero;

*entero = auxiliar;
}
else
{
anterior->sig = auxiliar;
auxiliar->sig = puntero;
}
}
void eliminar(struct lista **entero, int dato)
{
struct lista *puntero, *anterior;
puntero = *entero;
anterior = NULL;
while((puntero != NULL) && (puntero->dato < dato))
{
anterior = puntero;
puntero = puntero->sig;
}
if(puntero->dato != dato)
cout<<"El numero no existe "<
else
{
if(anterior == NULL) //1er lista
*entero = (*entero)->sig;
else
anterior->sig = puntero->sig;
delete puntero;
}
}
void recorrer(struct lista **entero)
{
struct lista *puntero;
puntero = *entero;
while(puntero != NULL)
{
cout< dato<< " ";
puntero = puntero->sig;
}
}
int buscar(struct lista **entero, int dato)
{
struct lista *puntero;
puntero = *entero;
while((puntero != NULL) && (puntero->dato < dato)) puntero = puntero->sig;
if(puntero->dato == dato)
return 1;
else

return 0;
}

Figura muestra la Salida en pantalla de programa

MS ACERCA DE LISTAS ENLAZADAS


En la implementacin de las listas enlazadas se pueden encontrar muchas
formas de representacin, dependiendo de los recursos que se tengan
relacionados con el dominio del lenguaje C++. Una forma ms sencilla de
representar una lista enlazada de nmeros enteros se presenta en el listado
llamado progra28.cpp en donde los datos ya estn predefinidos.
Progra28.cpp
#include <stdlib.h>
#include <iostream.h>
#include <conio.h>
struct lista
{
int nuevo;
struct lista *sig;
};
int main()
{
clrscr();
struct lista *L;

struct lista *P;


int i;
L=NULL;
cout<<"RESULTADO DE LA LISTA\n\n";
for(i=1;i<=6;i++)
{
cout <<<"-";
P=(struct lista *)malloc(sizeof(struct lista)); //Reserva memoria para el nodo
P-> nuevo=3; //Introduce la informacin
P->sig=L; //Reorganiza
L=P; //los enlaces
}
cout < nuevo <<"\n\n";
cout << "Donde " < nuevo <<" es el Nuevo nodo insertado al final ";
free (P);
getch();
return 0;
}
El resultado de la salida en pantalla de progra28.cpp se visualiza en la figura 40,
que se muestra continuacin.

ANLISIS DE PROGRA28.CPP
Al analizar un poco el cdigo de progra28.cpp se tiene definida una
estructura llamada lista, que tiene como miembros a un puntero llamado *nuevo y
a *sig que es el enlace al siguiente elemento de la lista y es del tipo de la
estructura, al igual que los punteros *L y *P, utilizados para gestionar la lista. Se
define la variable i que es de tipo entero utilizada para el recorrido del ciclo for. El
cual est predefinido para que repita el proceso de insertar elementos 5 veces al
estar definido as: for(i=1;i<=6;i++).
El puntero P es utilizado para la reserva de memoria que se hace por medio
de Malloc(), lo que indica que P guardar los elementos que se inserten a la lista,
pero se requiere otro puntero que recorra la lista y esa labor la hace L.
Siguiendo algortmicamente las instrucciones del programa se tiene que se
almacena un nuevo dato que es el nmero 3 y que este se guarda en el apuntador
P tal como lo indica la instruccin p->nuevo=3.
Con la instruccin P->sig=L; se hace que p apunte al siguiente elemento de
lista posteriormente se reorganizan los enlaces en la instruccin L=P.

Finalmente se imprime los datos de ciclo for almacenados en la variable, es decir


los nmeros del 1 al 5, seguido del valor almacenado en P para el cual se reserv
memoria que se libera antes de finalizar el programa.
Continuando con la implementacin de las listas enlazadas, vale la pena analizar
el siguiente cdigo de progra29.cpp, implementado con punteros que crea una
lista enlazada de 6 nmeros enteros ingresados por teclado en tiempo de
ejecucin, imprime todos sus elementos y adicionalmente arroja la sumatoria de
los elementos de la lista.
PROGRA29.CPP
include <stdlib.h>
#include <iostream.h>
#include <conio.h>
struct nodo
{
int dato;
struct nodo *sig;
}*l=NULL,*primero=NULL;
int main()
{
clrscr();
int acumulador=0;
int i=0, vector[6];
cout<<"IMPLEMENTACION DE UNA LISTA ENLAZADA\n\n";
cout<<"Ingrese 6 numeros\n";
for(i;i<6;i++)
{
cin>> vector[i];
acumulador = acumulador + vector[i];
}
for(i;i<6;i++)
{
primero=(struct nodo *)malloc(sizeof(struct nodo));
primero->dato=vector[i-1];
primero->sig = l;
l = primero;
}
cout<<"\nLista creada. Preseione una tecla ";
getch();
cout<<"\nLa sumatoria de la lista es : " <
cout<<" \n";
while(l!=NULL)
{
cout<< l->dato;
l=l->sig;

}
free(primero);
getch();
return 0;
}
El resultado despus de haber compilado y depurado el cdigo es el que se
visualiza en la figura

LISTAS DOBLEMENTE ENLAZADAS


Las listas doblemente enlazadas son un tipo de lista lineal en la que cada
nodo tiene dos enlaces, uno que apunta al nodo siguiente, y el otro que apunta al
nodo anterior.
Las listas doblemente enlazadas no necesitan un nodo especfico para
acceder a ellas, ya que presentan una gran ventaja comparada con las listas
enlazadas y es que pueden recorrerse en ambos sentidos a partir de cualquier
nodo de la lista, ya que siempre es posible desde cualquier nodo alcanzar
cualquier otro nodo de la lista, hasta que se llega a uno de los extremos.
La creacin de las listas doblemente enlazadas se hace de igual manera
que con las listas enlazadas, es decir a travs de una estructura, la diferencia
radica en que para esta tipo de lista doble se requiere otro enlace que apunte al
nodo anterior. He aqu la definicin de la estructura llamada Lista Doble.
struct ListaDoble {
int dato;
struct nodo *siguiente;
struct nodo *anterior;
};
REPRESENTACIN GRFICA DE UNA LISTA DOBLEMENTE ENLAZADA
Una forma grfica de representar una lista doblemente enlazada se puede
visualizar en la figura se muestra a continuacin.

El movimiento a travs de listas doblemente enlazadas es ms flexible, ya


que como se ver en esta leccin las operaciones de bsqueda, insercin y
borrado, tambin tienen algunas ventajas significativas frente a las listas
enlazada".
OPERACIONES BSICAS CON LISTAS DOBLEMENTE ENLAZADAS
Nuevamente se tienen las mismas operaciones sobre este tipo listas:
Aadir o insertar elementos. Puede llevarse a cabo en cualquier lugar de la
lista.
Buscar o localizar elementos. Dada una caracterstica especial.
Borrar elementos. Permite elegir el elemento a eliminar.
Moverse a travs de la lista, siguiente y anterior.
Se intentar analizar algunos casos posibles de insercin, eliminacin y
visualizacin de elementos en listas doblemente enlazadas.
IMPLEMENTACIN DE UNA LISTA DOBLEMENTE ENLAZADA
En el siguiente listado se presenta el cdigo completo de progra30.cpp, el cual
crea una lista doblemente enlazada con punteros donde se incluye un men de
opciones para su interaccin, adicionalmente presenta funciones para crear la lista
del registro de personas, visualiza la lista, elimina un registro y busca un registro
dentro de la lista.
Progra30.cpp
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream.h>
struct direc
{
char nombre[30];
char ciudad[20];
char codigo[10];
struct direc *sig; //PUNTERO A LA SIGUIENTE ENTRADA
struct direc *ant; //PUNTERO AL REGISTRO ANTERIOR
};

struct direc *ppio; //PUNTERO A LA PRIMERA ENTRADA ALA LISTA


struct direc *final; //PUNTERO ALA ULTIMA ENTRADA
struct direc *buscar(char *);
void intro(void);
void buscar(void);
void listar(void);
void eliminar(struct direc **, struct direc **);
void dl_insert(struct direc *i, struct direc **ppio, struct direc **final);
void leecad(char *, char *, int), mostrar(struct direc *);
int menu(void);
int main(void)
{
clrscr();
ppio = final = NULL; //INICIALIZA LOS PUNTEROS
for(;;)
{
switch(menu())
{
case 1: intro(); //INTRODUCIR UNA DIRECCION
break;
case 2: eliminar(&ppio, &final); //ELIMINA UNA DIRECCION
break;
case 3: listar();//MOSTRAR LA LISTA
break;
case 4: buscar();//ENCONTRAR UNA DIRECCION
break;
case 5: exit(0);
}
}
}
//selecionar una operacion
int menu(void)
{
char s[80];
int c;
cout<<"\nLISTA DOBLEMENTE ENLAZADA\n\n";
cout<<"1. Introducir una direccion" <
cout<<"2. Eliminar una direccin" <
cout<<"3. Listar el archivo" <
cout<<"4. Buscar" <
cout<<"5. Salir" <
do
{
cout<<"\nIntroduce una opcion: ";
gets(s);

c = atoi(s);
}while(c<0 || c>5);
clrscr();
return c;
}
//Introducir nombres y direcciones
void intro(void)
{
struct direc *info;
for(;;)
{
info = (struct direc *)malloc(sizeof(struct direc));
if(!info)
{
cout<<<"no hay memoria";
return;
}
leecad("\nIntroduce el nombre: ", info->nombre, 30);
if(!info->nombre[0]) break; //parar el proceso
leecad("Introduce la ciudad: ", info->ciudad, 20);
leecad("Introduce el codigo: ", info->codigo, 10);
dl_insert(info, &ppio, &final);
}
clrscr();
}
/* Esta funcion lee una cadena de longitud maxima cont
y previene el desbordamiento de la cadena. tambien
visualiza un mensaje indicativo */
void leecad(char *indic, char *s, int cont)
{
char p[255];
do
{
printf(indic);
fgets(p, 254, stdin);
}while(strlen(p) > cont);
p[strlen(p)-1] = 0; //Eliminar el salto de linea
strcpy(s, p);
}
// crear una lista doblemente enlazada
void dl_insert(
struct direc *i, //nuevo elemento
struct direc **ppio, //primer elemento de la lista
struct direc **final //ultimo elemento de la lista
)
{

struct direc *ant, *p;


if(*final == NULL) //primer elemento de la lista
{
i->sig = NULL;
i->ant = NULL;
*final = i;
*ppio = i;
return;
}
p = *ppio; //principio de la lista
ant = NULL;
while(p)
{
if(strcmp(p->nombre, i->nombre) <0)
{
ant = p;
p = p->sig;
}
else
{
if(p->ant)
{
p->ant->sig = i;
i->sig = p;
i->ant = p->ant;
p->ant = i;
*ppio = i;
return;
}
i->sig = p; //nuevo primer elemento
i->ant = NULL;
p->ant = i;
*ppio = i;
return;
}
}
ant->sig = i; //ponerlo en el final
i->sig = NULL;
i->ant = ant;
*final = i;
}
//eliminar un elemento de la lista
void eliminar(struct direc **ppio, struct direc **final)
{
struct direc *info;
char s[80];

leecad("Introduce el nombre: ", s, 30);


info = buscar(s);
if(info)
{
if(*ppio==info)
{
*ppio=info->sig;
if(*ppio) (*ppio)->ant =NULL;
else *final = NULL;
}
else
{
info->ant->sig = info->sig;
if(info != *final)
info->sig->ant = info->ant;
else
*final = info->ant;
}
free(info); //devolver la memoria al sistema
}
clrscr();
}
//buscar una direccion
struct direc *buscar(char *nombre)
{
struct direc *info;
info = ppio;
while(info)
{
if(!strcmp(nombre, info->nombre))
return info;
info = info->sig; //obtener siguiente direccion
}
cout<<"nombre no encontrado" <
return NULL; //no encontrado
}
//mostrar la lista entera
void listar(void)
{
struct direc *info;
info = ppio;
while(info)
{
mostrar(info);
info = info->sig; //obtener la siguiente direccion
}

cout<<
}
// esta funcion imprime realmente los campos de cada direccion
void mostrar(struct direc *info)
{
cout<nombre<<"-";
cout<ciudad<<"-";
cout<codigo<<"-";
cout<<
}
//buscar un nombre en la lista
void buscar(void)
{
char nombre[40];
struct direc *info;
cout<<"Introduce el nombre a encontrar: ";
gets(nombre);
info = buscar(nombre);
if(!info)
cout<<"no encontrado";
else mostrar(info);
getch();
clrscr();
}
La salida en pantalla de progra30.cpp como implementacin de una lista
doblemente enlazada se puede visualizar en la figura se muestra a continuacin.

SOBRECARGA DE OPERADORES EN C+
La
sobrecarga de operadores, aunque puede ser una capacidad
extica, la mayora de personas las usa implcita y
regularmente se valen de los operadores sobrecargados.
Por ejemplo, el operador de suma (+) funciona de manera

diferente sobre los enteros, puntos flotantes y dobles. No


obstante dicho operador funciona muy bien con las variables
int, float y double y varios otros tipos integrados han sido
sobrecargados por el propio lenguaje C++.
Los operadores se sobrecargan escribiendo una definicin de funcin (con su
encabezado y cuerpo) de manera habitual, excepto que el nombre de la funcin
ahora se vuelve la palabra clave operator, seguida por el smbolo del operador que
se sobrecarga. Por ejemplo el nombre de la funcin operator+ sirve para
sobrecargar el operador de suma (+).
Para utilizar un operador sobre objetos de una clase, dicho operador debe ser
sobrecargado, con dos excepciones: el operador de asignacin (=) puede
utilizarse con cualquier clase, sin sobrecarga explcita.
El comportamiento predeterminado del operador (=) es una asignacin a nivel de
miembros de los datos miembro de la clase. El operador de direccin (&) tambin
puede utilizarse sin sobrecarga con objetos de cualquier clase, simplemente
devuelve
la
direccin
de
memoria
del
objeto.
La sobrecarga de operadores no es automtica; el programador debe escribir
funciones de sobrecarga de operadores que realicen las operaciones deseadas. A
veces conviene que estas funciones se hagan funciones miembro, en otras
ocasiones conviene que sean funciones friend, ocasionalmente puede hacerse
funciones no miembro, no friend.
Es posible llegar a los extremos de la sobrecarga, como sobrecarga, como
sobrecargar el operador + para que realice operaciones tipo resta. Tales empleos
de la sobrecarga hace que sea muy difcil entender el programa.
Una lista de operadores que pueden o no sobrecargarse es la siguiente:
Operadores que pueden sobrecargarse
+
*
/
%
^
^&
|
!
=
<
>

+=
-=
*=
/=
%=
A=
&=
!=
<<
>>
>>=
<<=
==
!=
<=
>=
&&
||
++
-->*

->
[]
()
new
delete
new [ ]
delete []

OPERADORES QUE NO PUEDEN SOBRECARGARSE


.
.*
::
?:
sizeof
Los operadores &, *, + y - tiene versiones unarias y binarias, estas versiones
unarias y binarias se pueden sobrecargar por separado.
No es posible crear nuevos operadores; slo se pueden sobrecargar los
operadores existentes, esto desgraciadamente, evita que el programador use
notaciones como ** como en BASIC para la exponenciacin.
La sobrecarga de un operador de asignacin y de uno de suma para permitir
instrucciones como:
obj eto2=obj eto2+obj eto1;
no implica que el operador += tambin este sobrecargado para permitir
instrucciones como:
obj eto2 +=obj eto1;
tal comportamiento puede lograrse explcitamente sobrecargando el operador +=
de dicha clase.
La funciones de operador pueden ser funciones miembro o funciones no miembro,
estas ltimas con frecuencia se hacen friend por razones de desempeo. Las
funciones miembro utilizan implcitamente el operador this para obtener uno de los
argumentos de su objeto de clase.
Tal argumento de funcin puede debe listarse explcitamente en una llamada de
funcin no miembro.
Cuando una funcin de operador se implemente como funcin miembro, el
operador de la izquierda (o el nico) debe ser un objeto de clase (o una referencia
a un objeto de clase) de la clase del operador. Si el operador de la izquierda debe
ser un objeto de una clase diferente o un tipo integrado, esta funcin operador
debe implementarse como funcin no miembro.

Una funcin de operador no miembro debe ser friend si necesita acceder


directamente a miembros prvate o protected la clase.
Las funciones miembro de los operadores de una clase especfica se llaman slo
cuando el operando de la izquierda de un operador binario especficamente es un
objeto de esa clase, o cuando el operando de un operador unario es un objeto de
esa clase.
Ejemplo
Creacin de una clase string y sobrecarga de la mayora de sus operadores.
#include<iostream.h>
#include<string.h>
#include<stdlib.h>
#include<conio.h>
#include<assert.h>
enum bool { false, true };
class string {
int size;
char *ptr;
public:
string (char []=""); //constructor predeterminado
string (string &); //constructor por copia
~string();
//destructor
string & operator= (string &); //asignacin
bool operator== (string &);
//prueba si s1=s2
bool operator!= (string &);
//prueba si s1!=s2
bool operator! ();
//prueba si string esta vacia
bool operator< (string &);
//prueba si s1<s2
bool operator> (string &);
//prueba si s1>s2
bool operator<= (string &);
//prueba si s1<=s2
bool operator>= (string &);
//prueba si s1>=s2
string & operator+= (string &); //concatenacin
char operator[] (int);
//operador de subndice
string operator() (int, int); //devuelve una subcadena
int longitud (void);
//devuelve longitud de la cadena
friend ostream & operator<< (ostream &, string &);
friend istream & operator>> (istream &, string &);
};
string :: string (char * cadena){
size=strlen(cadena);
ptr=new char[size+1];
if(ptr==NULL){ cout<<"No hay memoria"; exit(0); }
strcpy(ptr, cadena);
}

string :: string (string & copia){


size=strlen(copia.ptr);
ptr=new char[size+1];
if(ptr==NULL){ cout<<"No hay memoria"; exit(0); }
strcpy(ptr, copia.ptr);
}
string :: ~string(){
delete [] ptr;
}
string & string :: operator= (string & s){
if(&s != this){
//evita la autoasignacin
delete [] ptr;
//evita fugas de memoria
size=s.size;
ptr=new char[size+1];
strcpy(ptr, s.ptr);
}
else cout<<"Intento de asignar un objeto a si mismo";
return (*this);
//habilita asignaciones en cascada
}
bool string :: operator== (string & s){
if(!strcmp(ptr, s.ptr)) return (true);
return (false);
}
bool string :: operator!= (string & s){
if(!(*this==s)) return(true); //usa sobrecarga de ==
return(false);
}
bool string :: operator! (){
if (size==0) return true;
return false;
}
bool string :: operator< (string & s){
if (strcmp(ptr, s.ptr)< 0) return true;
return false;
}
bool string :: operator> (string & s){
if (s < *this) return true;
return false;
}
bool string :: operator<= (string & s){
if( !( s < *this) ) return true;
return false;
}
bool string :: operator>= (string & s){
if( !(s > *this) ) return true;
return false;

}
string & string :: operator+= (string & s){
char *temps=ptr;
size+=s.size;
ptr=new char[size+1];
if(ptr==NULL){ cout<<"No hay memoria"; exit(0); }
strcpy(ptr, temps);
strcat(ptr, s.ptr);
delete [] temps;
return (*this);
//habilita llamadas en cascada
}char string :: operator[] (int num){
assert(num>=0 && num<size); //prueba si num est en el rango
return (ptr[num]);
}
//Devuelve subcadena que comienza en: inicio y de longitud: subsize
string string :: operator() (int inicio, int subsize){
//asegura que inicio este en el rango y que subsize sea >=0
assert(inicio>=0 && inicio<size && subsize >=0);
string *subptr= new string;
//string vaca
if(subptr==0){ cout<<"No hay memoria"; exit(0); }
//determina la longitud de la subcadena
if((subsize==0) || (inicio+ subsize> size))
subptr->size= size- inicio+ 1;
else
subptr->size= subsize+1;
//asigna memoria para la subcadena
delete subptr->ptr;
//borra el arreglo de caractres
subptr->ptr= new char[subsize];
if(subptr->ptr==NULL){ cout<<"No hay memoria"; exit(0); }
//copia la subcadena a la nueva string
strncpy(subptr->ptr, & ptr[inicio], subptr->size);
subptr->ptr[subptr->size]='\0'; //termina string
return (*subptr); //devuelve la nueva string
}
int string :: longitud (void){
return (size);
}
ostream & operator<< (ostream & salida, string & s){
salida<< s.ptr;
return (salida); //habilita el proceso en cascada
}
istream & operator>> (istream & entrada, string & s){
entrada>> s.ptr;
return (entrada); //habilita proceso en cascada
}

void main(void){
textcolor(BLACK);
textbackground(WHITE);
clrscr();
string s1("hola"), s2(" amigos"), s3;
//probando operadores de igualdad y relacionales
cout<<"s1: " <<s1 <<" , s2: " <<s2 <<" , s3: " <<s3;
cout<<endl<<endl<<"Resultados al comparar s1 y s2: "
<<endl<<"Resultado de s1==s2: " << (s1==s2 ? "verdadero" : "falso")
<<endl<<"Resultado de s1!=s2: " << (s1!=s2 ? "verdadero" : "falso")
<<endl<<"Resultado de s1> s2: " << (s1> s2 ? "verdadero" : "falso")
<<endl<<"Resultado de s1< s2: " << (s1< s2 ? "verdadero" : "falso")
<<endl<<"Resultado de s1>=s2: " << (s1>=s2 ? "verdadero" : "falso")
<<endl<<"Resultado de s1<=s2: " << (s1<=s2 ? "verdadero" : "falso");
//prueba operador sobrecargado (!)
cout<<endl<<endl<<"Probando !s3: ";
if(!s3){
cout<<"s3 esta vacio, asignando s1 a s3";
s3=s1;
cout<<"ns3: " << s3;
}
//probando operador sobrecargado de concatenacion
cout<<endl<<endl<<"Resultado de s1+=s2: "<<endl;
s1+=s2;
cout<<"s1: " <<s1;
//probando operador sobrecargado []
cout<<", s1[8]= " <<s1[8];
//prueba del operador sobrecargado ()
cout<<endl<<endl<<"Cadena resultante de s1(5,6): " <<s1(5,6) ;
//prueba el constructor de copiado
string *s4= new string(s1);
cout<<endl<<endl<<"Constructor copia para *s4: " <<*s4;
//prueba del operador de asignacion =
cout<<endl<<endl<<"Asignando s3 a *s4, *s4: ";
*s4=s3;
cout<< *s4
<<endl<<"Longitud de *s4: " <<s4->longitud();
getch();
}

You might also like