Está en la página 1de 49

2.

Comandos del sistema

Capítulo anterior: 1 - Manejo de Directorios y Archivos


Capítulo siguiente: 3 - Comandos del sistema II

Administración de archivos

ls[opción(es)][archivo(s)]

Si introduce ls sin más datos ni parámetros, podrá ver un listado resumido con el
contenido del directorio en el que se encuentre en ese momento.

-l

lista detallada,

-a

para ver los archivos ocultos.

cp[opción(es)]archivo_original archivo_copia

Crea una copia de archivo_original en archivo_copia.

-i

Espera, dado el caso, una confirmación antes de sobreescribir un archivo_copia


existente.

-r

Copia recursiva (incluyendo subdirectorios)

mv[opción(es)]archivo_origenarchivo_destino

Hace una copia de archivo_origen en archivo_destino y a continuación borra el archivo


original.

-b

Crea una copia de seguridad antes de desplazar archivo_origen.

-i

Espera, dado el caso, una confirmación antes de sobreescribir un archivo_destino


existente.
rm[opción(es)]archivo(s)

Borra el archivo(s) indicado del sistema de archivos. Los directorios no serán borrados
con el comando rm a menos que se haya especificado de forma explícita a través del
parámetro -r.

-r

Borra, si existen, los subdirectorios existentes

-i

Espera una confirmación antes de borrar cada uno de los archivos

ln[opción(es)]archivo_origenarchivo_destino

Crea en archivo_destino una referencia cruzada dentro del sistema de archivos, (Link)
del archivo_origen con otro nombre. Normalmente este enlace apunta directamente a la
posición de archivo_origen dentro de un sistema de archivos. Si por el contrario se
ejecuta el comando ln con la opción -s, se creará un denominado enlace simbólico que
apuntará exclusivamente a la rama de archivo_origen y que por esa razón podrá ser
usado fuera de los límites del sistema de archivos.

-s

Crea un enlace simbólico.

cd[opción(es)]directorio

Cambia el directorio actual. Si sólo se introduciecd, se desplazará al directorio home.

mkdiropción(es)]directorio

Crea un nuevo directorio.

rmdir[opción(es)]directorio

Borra el directorio, pero sólo si está vacío.

chown[opción(es)]nombreusuario.grupoarchivo(s)

Cambia el dueño de un archivo, otorgándole la propiedad a nombreusuario.

-R

Cambia los archivos y directorios en todos los subdirectorios.

chgrp[opción(es)]nombregrupoarchivo(s)
Cambia el nombre del grupo al que pertenece el archivo por nombregrupo. El dueño del
archivo sólo puede cambiar este valor si pertenece tanto al grupo al que pertenecía el
archivo hasta ahora como al nuevo grupo al que pertenecerá el archivo.

chmod[opciones]modoarchivo(s)

Cambia los permisos de acceso a uno o varios archivos.

El parámetro modo tiene tres partes: grupo, acceso y tipo de acceso. grupo acepta los
siguientes caracteres:

para el usuario user,

para el grupo group,

para todos los demás: others.

+ y - se utilizan para permitir o denegar el acceso, de manera que: el símbolo +


permitirá el acceso y el símbolo - lo denegará.

Los tipos de acceso son controlados por las siguientes opciones:

para lectura read,

para escritura write,

Ejecutar archivos o cambiar de directorio eXecute.

Setuid-Bit; el programa se ejecutará con los privilegios del propietario del archivo.

gzip[parámetros]archivo(s)

Este programa comprime el contenido de archivos mediante unos complicados procesos


matemáticos. El nombre del archivo comprimido termina con .gz y debe ser
descomprimido antes de poder ser usado nuevamente. Si desea comprimir más de un
archivo o directorios completos, deberá usar además el comando tar.
-d

Descomprime el archivo comprimido gzip, recuperando éste su tamaño original y


pudiendo volver a ser utilizado de forma normal (corresponde al comando gunzip).

taropcionesnombrepaquetearchivo(s)

El comando tar agrupa uno o (normalmente) más archivos en un llamado paquete, que
luego se puede p.ej. comprimir.

tar es un comando muy complejo, que ofrece una gran cantidad de opciones. A
continuación le enseñamosalgunas de las combinaciones más usadas.

-f

La información generada por el proceso se escribe en un archivo y no se muestra en la


pantalla, como está previsto por defecto file.

-c

Crea un nuevo archivo tar create.

-r

Agrega archivos a un paquete existente.

-t

Muestra el contenido de un paquete.

-u

Agrega archivos al paquete, pero sólo si estos son más recientes que los existentes.

-x

Desempaqueta archivos de un paquete (extrae)

-z

Comprime con gzip el paquete generado.

-j

Comprime con bzip2 el paquete generado.

-v

Da los nombres de los archivos procesados.


Los archivos creados mediante tar terminan en .tar. Cuando el archivo tar ha sido
además comprimido con gzip, la terminación será .tar.gz, con bzip2, será .tar.bz2.

Encontrará aplicaciones de ejemplo en el apartado

locateprueba

Con el comando locate se puede averiguar en qué directorio se encuentra el archivo


especificado. Para ello también se puede usar los Comodines. El programa trabaja muy
rápido ya que no busca en el sistema de archivos, sino en una base de datos propia
creada a tal efecto. Éste es el mayor problema de estos comandos rápidos, ya que los
archivos creados posteriormente a la última actualización de esta base de datos, no se
tienen en cuenta.

Como root puede crear esta base de datos usando el comando updatedb.

updatedb[opción(es)]

Con este comando se puede actualizar de forma sencilla la base de datos requerida por
locate. Para conseguir que todos los archivos se tengan en cuenta, se debe ejecutar el
comando como root. También es posible, añadiendo al final del comando el símbolo &,
que el programa se ejecute en segundo plano, y así poder seguir trabajando mientras se
produce la actualización . (updatedb &).

find[Opción(en)]

Con el comando find puede buscar un archivo en un determinado directorio. El primer


argumento representa el directorio desde el que debe comenzar la búsqueda. La opción
-name requiere una cadena de búsqueda, en la que también se permite el uso de
Comodines. Al contrario que locate, find busca en el directorio especificado, no en una
base de datos.

3. Comandos del sistema II

Capítulo anterior: 2 - Comandos del sistema


Capítulo siguiente: 4 - Comandos del sistema III

Comandos para visualizar contenidos

cat[opción(es)]archivo(s)

Con el comando cat se ve el contenido del archivo elegido sin interrupciones.

-n

Numera el texto en el borde izquierdo.


less[opción(es)]archivo(s)

Con este comando se puede examinar el contenido del archivo elegido. Por ejemplo
puede subir y bajar media hoja de pantalla con las teclas BildAb y BildAuf con la tecla
espaciadora hasta una página entera hacia adelante. También puede desplazarse al
comienzo y al final del texto con las teclas Inicio y Fin. Y con la tecla Q puede cerrar
este modo de visualización.

grep[opción(es)]términodebúsquedaarchivo(s)

grep está pensado para buscar un determinado término de búsqueda en el archivo(s)


elegido. Si la búsqueda se ha realizado con éxito, el programa mostrará la línea en la
que se ha encontrado el término de búsqueda, así como el nombre del archivo.

-i

Ignora las diferencias entre mayúsculas y minúsculas

-l

Da sólo el nombre del archivo correspondiente y no el número de línea

-n

Numera, además, las líneas donde se encontró el texto buscado

-l

Da una lista de los archivos que no contengan el término de búsqueda

diff[opción(es)]archivo1archivo2

diff fue creado para comparar el contenido de dos archivos cualesquiera y mostrar en
una lista las líneas en las que se hayan detectado diferencias.

Los programadores utilizan con frecuencia este comando para enviar los cambios
realizados en sus programas sin necesidad de enviar todo el texto fuente.

-q

Indica tan sólo si existen diferencias entre el contenido de los dos archivos
seleccionados.

4. Comandos del sistema III

Capítulo anterior: 3 - Comandos del sistema II


Capítulo siguiente: 5 - Comandos del sistema IV
Sistema de archivos

mount[opción(es)][dispositivo]punto_de_montaje

Con ayuda de este comando se puede montar diferentes dispositivos de


almacenamiento. Con ello se entiende la unión de discos duros, CD-ROM y otras
unidades de disco con un directorio del sistema de archivos Linux.

-r

monta el dispositivo como sólo lectura

-t sistema de archivos

Especifica el sistema de archivos. Los más comunes son: ext2 para discos duros de
Linux, msdos para dispositivos MS-DOS, vfat para sistema de archivos de particiones
Windows y iso9660 para CDs.

En el caso de unidades que no estén definidas en el archivo /etc/fstab, se deberá también


especificar el tipo de dispositivo. En este caso, sólo el root podrá montarlo. Para que el
sistema de archivos pueda ser montado por otros usuarios, introduzca la opción user en
la línea correspondiente del archivo/etc/fstab (separado por comas) y guarde los
cambios. Para más información, diríjase a mount.

umount[opción(es)]puntodemontaje

Con este comando se retira una unidad de disco del sistema de archivos. Ejecute este
comando antes de retirar un medio de almacenamiento de la unidad de discos. ¡De lo
contrario se expone a una pérdida de datos! Por norma general, tanto el comando mount
como el comando umount sólo pueden ser ejecutados por root. Excepción: Cuando,
para el dispositivo, aparece la opción user en el archivo /etc/fstab.

5. Comandos del sistema IV

Capítulo anterior: 4 - Comandos del sistema III


Capítulo siguiente: 6 - Comandos del sistema V

Información

df[opción(es)][directorio]

Si se ejecuta el comando df disk free sin ninguna opción, se nos dará una estadística
sobre el espacio total, el ocupado y el libre de todas las unidades de disco montadas. Si
por el contrario se introduce un directorio, se mostrarán sólo las estadísticas de la
unidad de disco que incluye dicho directorio.

-H
Nos enseña el número de bloques ocupados en gigabytes, megabytes o kilobytes ? de
forma legible para el ser humano human readable.

-t

Tipo de unidad (ext2, nfs, etc.).

du[opción(es)][ruta]

Este comando, usado sin opciones, indica el espacio total de almacenamiento utilizado
por todos los archivos del directorio en el que nos encontremos. Si existen
subdirectorios en él, también se indicará su tamaño total.

-a

Indica el tamaño de cada uno de los archivos.

-h

Listado en forma legible para el ser humano.

-s

Nos enseña tan sólo el tamaño total.

free[opción(es)]

free nos muestra el tamaño total y el usado de memoria física y de intercambio.

-b

Indicado en bytes,

-k

Indicado en kilobytes,

-m

Indicado en megabytes

date[opción(es)]

Ejecutando este pequeño programa, se nos informará de la hora del sistema. Además
como root, se puede modificar con este comando la hora del sistema. Encontrará más
detalles en la Manpage de (date).

Procesos

top[opción(es)]
Por medio de top obtendrá una lista rápida de todos los Procesos que se estén
ejecutando. Pulsando la tecla h se le enseñara una página con aclaraciones y con las
opciones más importantes para adecuar este programa a sus necesidades.

ps[opción(es)][proceso-ID]

Si se ejecuta sin opciones se mostrarán en una tabla todos los procesos propios, es decir,
todos los programas y procesos que haya inicializado uno mismo. Tenga cuidado al usar
las opciones de este comando; pues no se debe anteponer un guión.

aux

Proporciona una lista detallada de todos los procesos, sin tener en cuenta el dueño.

kill[opción(es)]proceso-ID

A veces, desafortunadamente, nos encontramos con programas que no se pueden cerrar


de forma normal. Con el comando kill, se puedeeliminar todos los procesos muertos
con ayuda del ID del proceso (ver top y ps).

Para ello envía una señal llamada TERM que ordena al programa cerrarse a sí mismo. Si
esto tampoco sirve tenemos aún otro parámetro de gran ayuda:

-9

Envía en lugar de una señal tipo TERM una señal tipo KILL, lo que ocasiona que el
proceso sea liquidado por el sistema operativo, consiguiendo en casi todos los casos que
el proceso especificado se termine.

killall[opción(es)]nombreproceso

Este comando funciona de forma equivalente a kill, sólo que para este comando basta
con dar el nombre del proceso - y no su ID - para matar todos los procesos que tengan
ese nombre.

6. Comandos del sistema V

Capítulo anterior: 5 - Comandos del sistema IV


Capítulo siguiente: 7 - Comandos del Sistema VI

Red

ping[opción(es)]nombre_computadora|direcciónIP

ping es el comando por excelencia para comprobar que las funciones básicas de una red
TCP/IP funcionan correctamente. La herramienta manda a otro ordenador un pequeño
paquete de datos, ordenándole que una vez recibido lo devuelva de inmediato. Si esto
funciona, ping se lo indicará con un mensaje, con lo que se asegura la capacidad de
transmisión básica de la red.

-c

número: Determina el número total de paquetes enviados, tras lo cual el programa se


cierra. No hay limitaciones por defecto.

-f

Flood (desbordamiento) ping: Envía tantos paquetes de datos como sea posible.
Comando usado para probar al límite la capacidad de una red, pero que sin embargo
sólo puede ser usado por root.

-i

valor: Segundos transcurridos entre el envío de dos paquetes de datos; el valor


predeterminado es un segundo.

nslookup

Para transformar nombres de dominios en direcciones IP existe el denominado Domain


Name System. Con esta herramienta puede dirigir preguntas al servicio de información
correspondiente (servidor DNS).

telnet[opción(es)]nombre_computadora o direcciónIP

Telnet es en realidad un protocolo de Internet que permite trabajar a través de la red con
otra computadora (remota).

Pero Telnet también es el nombre de un programa Linux que utiliza este mismo
protocolo para permitir el trabajo con otras máquinas sin tener que estar sentado delante
de ellas.

Aviso

Procure no utilizar Telnet en redes en las que pueda ser espiado por terceros. En Internet
se deberían usar sobre todo métodos de transmisión cifrados como p.ej. ssh y así
impedir el peligro que conlleva un uso malintencionado de su contraseña (ver ssh).

7. Comandos del Sistema VI

Capítulo anterior: 6 - Comandos del sistema V


Capítulo siguiente: 8 - Comandos del Sistema VII

Otros
passwd[opción(es)][nombre_de_usuario]

Con este comando, cada usuario tiene en todo momento la posibilidad de cambiar su
propia contraseña. El superusuario root tiene además permiso para cambiar la
contraseña de cualquier usuario.

su[opción(es)][nombredeusuario]

su permite cambiar el login del usuario durante una sesión. Si no se utiliza ningún
parámetro, la línea de comando exigirá la contraseña de root. Una vez introducida ésta
correctamente se obtendrán todos los derechos del superusuario. También se puede usar
el entorno de otro usuario introduciendo detrás del comando el nombre del usuario y
posteriormente la contraseña correcta del mismo. root no necesita introducir esta
contraseña. Es decir, con los derechos de superusuario se puede asumir sin problemas la
identidad de cualquier usuario.

halt[opción(es)]

Para evitar la pérdida de datos siempre debería apagar su computadora con este
programa.

reboot[Opción(es)]

Funciona como el comando halt, pero la computadora se volverá a iniciar tras apagarse.

clear

De vez en cuando ocurre que la consola está tan llena de líneas de texto que una
limpieza no le iría nada mal. Este comando se usa justamente para eso y no tiene
ninguna opción.

8. Comandos del Sistema VII

Capítulo anterior: 7 - Comandos del Sistema VI


Capítulo siguiente: 9 - Comandos y programas

Editor vi

El manejo de vi es un poco peculiar, sin embargo tiene preferencia en este manual,


porque existe en cualquier sistema operativo parecido a UNIX y forma parte de la
instalación predeterminada de Linux. Además, el control de este editor es totalmente
uniforme y libre de equivocaciones. Finalmente: Si no funciona nada, vi aún funciona.
La breve explicación que presentamos a continuación le servirá para utilizar las
funciones básicas de vi para editar z. B. diferentes archivos de configuración.

vi conoce 3 modos de operar:

- Modo de comandos command mode


Todas las pulsaciones de teclas se interpretan como parte de un comando.

- Modo de inserción insert mode

Las pulsaciones de teclas se interpretan como texto que se introduce.

- Modo de comandos complejos last line mode

Modo para comandos complejos que se editan en la última línea.

Las órdenes más importantes del modo de comandos son:

Tabla 21.2. Comandos básicos del editor vi

cambia al modo de inserción (los caracteres se introducen en la posición actual del


i
cursor).
cambia al modo de inserción (los caracteres se introducen detrás de la posición
a
actual del cursor).
A cambia al modo de inserción (los caracteres se añaden al final de la línea).
R cambia al modo de inserción (sobrescribe el texto anterior).
r cambia al modo de inserción sobrescribiendo un solo carácter.
cambia al modo de inserción (el carácter en la posición del cursor se sobrescribe con
s
el carácter nuevo).
C cambia al modo de inserción (el resto de la línea se reemplaza por el texto nuevo).
o cambia al modo de inserción (detrás de la línea actual se añade una línea nueva).
cambia al modo de inserción (por delante de la línea actual se añade una línea
O
nueva).
x borra el carácter actual.
dd borra la línea actual.
dw borra hasta el final de la palabra actual.
cw cambia al modo de inserción (el resto de la palabra actual se sobrescribe).
u deshace el último comando.
J añade la siguiente línea a la actual.
. repite el último comando.
: cambia al modo de comandos complejos.

Es posible anteponer una cifra a cualquier comando. Esta cifra indica el número de
veces que se debe repetir el comando que sigue. z. B. 3dw borra tres palabras seguidas,
10x borra diez caracteres a partir de la posición del cursor y 20dd borra 20 líneas.

Los comandos más importantes del modo de comandos complejos:

Tabla 21.3. Comandos complejos del editor vi

:q! sale de vi sin grabar los cambios.


:w nombre_archivo graba bajo el nombre nombre_archivo.
:x graba el archivo modificado y sale del editor.
:e Nombrearchivo edita (carga) nombre_archivo.
:u deshace el último comando de edición.

Para cambiar al modo de comandos dentro del modo


de inserción se debe pulsar la tecla ESC.

9. Comandos y programas

Capítulo anterior: 8 - Comandos del Sistema VII

Comandos y programas :

dmesg - Muestra los mensajes acaecidos durante el proceso de arranque.


lspci - Muestra los perifericos conectados al puente pci.
lsmod - Muestra los módulos cargados en el sistema.
whatis - Seguido de un nombre de fichero muestra una breve descripción de éste. ej.
whatis chmod
whereis - Seguido de un nombre de fichero muestra la ubicación de éste. ej. whereis
chmod
uname - Muestra el nombre de la máquina. ej. uname -a
mkdir - Crea un nuevo directorio. ej. mkdir /rafa/work
rmdir - Borra directorios vacios. *2
bc -Calculadora
rm -Borra ficheros. ej. rm -f lista.txt
free - Muestra estadisticas de memoria ram.
df - Muestra estadisticas de espacio en el disco.
cd - Cambia a directorio.
cp - Copia un fichero en el lugar especificado. ej. cp /lista.txt /rafa/work/lista.txt
mv - Mueve o renombra ficheros al lugar especificado. ej. mv /rafa/lista.txt
/rafa/work/lista.txt
ls - Muestra el contenido de un directorio o un fichero especifico.
man - Seguido del nombre de un programa muestra el manual de este. ej. man echo
modprobe -Seguido del nombre de un módulo carga el susodicho. ej. modprobe 8139too
reboot - Reinícia el sistema automáticamente.
halt - Apaga el sistema automáticamente.*3
date - Muestra la fecha y hora actual.
ln - Crea enlaces ( Accesos directos ) ej. ln -s /rafa/lista.txt
/rafa/Desktop/lista.txt
ps - Muestra la lista de los procesos activos. ej. ps -d
Kill - Mata procesos activos. ej. killall -9 wine
pwd - Nos muestra el camino ( path ) del directorio actual.
date - Muestra la fecha del sistema.
cal - Muestra un calendario.
du - Muestra el uso del disco. ej. du /rafa/work/games
less - Muestra ficheros de texto ej. less leemé.txt*4
exit - Salir de la sesión actual.
netstat - Muestra el estado de la red. ej. netstat -natu
ifconfig - Muestra la configuración de las interfaces de red
su - Invoca al superusuario ( root ) ( / ) o a cualquier otro usuario
tar - Descomprime ficheros. ej. tar xvfz xpde.tar.gz
mpg123 - Reproduce ficheros .mp3 ej. mpg123 /work/musica/mpg123 *.mp3
burnmp3 - Graba cd's en formato .mp3 o .ogg
nmap - Escanea la red. ej. nmap -sT 192.168.1.*
startx - Arranca el servidor X
chmod - Cambia el modo de un fichero. ej chmod 666 /dev/nvidia0
chown - Cambia el propietario de un fichero ej chown root.root /usr/local/bin/kradio

1: Algunos programas requieren de cierto permiso o modo para poder funcionar bajo un
usuario corriente. ( chmod, chown, sudo )

2: Para borrar un directorio lleno, usa la siguiente línea: rm -rf ( remove recursive
force ) ( borrar recursivamente forzar ) seguida del nombre del directorio a borrar ej. rm
-rf /home/alan/wor

3: Si por ejemplo queremos que el equipo se apague dentro de x minutos, ( Dónde x es


el número de minutos ) el comando a usar sería: shutdown -h +x nowej. para 4 horas;
shutdown -h +240 now

1. Introducción

Capítulo siguiente: 2 - Diferencias entre C y C++

Los programas estructurados se basan en estructuras de control bien definidas, bloques


de código, subrutinas independientes que soportan recursividad y variables locales. La
esencia de la programación estructurada es la reducción de un programa a sus elementos
constituidos.

La programación orientada a objetos (POO), permite descomponer un problema en


subgrupos relacionados. Cada subgrupo pasa a ser un objeto autocontenido que contiene
sus propias instrucciones y datos que le relacionan con ese objeto. Todos los lenguajes
POO comparten tres características: Encapsulación, Polimorfismo y Herencia.

ENCAPSULACIÓN: Es el mecanismo que agrupa el código y los datos que maneja.


Los mantienen protegidos frente a cualquier interferencia y mal uso. Cuando el código y
los datos están enlazados de esta manera se ha creado un objeto. Ese código y datos
pueden ser privados para ese objeto o públicos para otras partes del programa.

POLIMORFISMO: Es la cualidad que permite que un nombre se utilice para dos o


más propósitos relacionados pero técnicamente diferentes. El propósito es poder usar un
nombre para especificar una clase general de acciones. Por ejemplo en C tenemos tres
funciones distintas para devolver el valor absoluto. Sin embargo en C++ incorpora
Polimorfismo y a cada función se puede llamar abs(). El Polimorfismo se puede aplicar
tanto a funciones como a operadores.
HERENCIA: Proceso mediante el cual un objeto puede adquirir las propiedades de
otro objeto. La información se hace manejable gracias a la clasificación jerárquica.

OBJETO: Conjunto de variables y funciones pertenecientes a una clase encapsulados.


A este encapsulamiento es al que se denomina objeto. Por tanto la clase es quien define
las características y funcionamiento del objeto.

2. Diferencias entre C y C++

Capítulo anterior: 1 - Introducción


Capítulo siguiente: 3 - Creación de Clases y Objetos

Aunque C++ es un superconjunto de C, existen algunas diferencias entre los dos. En


primer lugar, en C cuando una función no toma parámetros, su prototipo tiene la palabra
void. Sin embargo en C++ void no es necesario(opcional).

Prototipo en C: char f1(void);


Prototipo en C++: char f1();

Otra diferencia entre C y C++ es que en un programa de C++ todas las funciones deben
estar en forma de prototipo, en C los prototipos se recomiendan, pero son opcionales.
También si una función de C++ es declarada para devolver un valor obligatoriamente la
sentencia return debe devolver un valor, en C no es necesario que se devuelva.

Otra diferencia es el lugar donde se declaran las variables locales. En C, deben ser
declaradas solo al principio del bloque, mientras que en C++ las variables se pueden
declarar en cualquier punto. Aunque es conveniente realizarlo siempre al comienzo de la
función.

3. Creación de Clases y Objetos

Capítulo anterior: 2 - Diferencias entre C y C++


Capítulo siguiente: 4 - Mi Primer Programa

La base del encapsulamiento es la clase, a partir de ellas se le dan las características y


comportamiento a los objetos. Lo primero es crear la clase y después en la función main
que sigue siendo la principal crearemos los objetos de cada una de las clases. Las
variables y funciones de una clase pueden ser publicas, privadas o protegidas. Por
defecto si no se indica nada son privadas.

Estos modificadores nos indican en que partes de un programa podemos utilizar las
funciones y variables.
private: Solo tendrán acceso los de la misma clase donde estén definidos.
public: Se pude hacer referencia desde cualquier parte del programa.
protected: Se puede hacer referencia desde la misma clase y las subclases.
Creación de una clase:
class nomb_clase{
funciones y variables privadas;
public:
funciones y variables publicas;
}

Creación del objeto:


nomb_clase nombre_objeto1;
nomb_clase nombre_objeto2;

Llamadas a las funciones de una clase:


nombre_objeto.nomb_funcion(parámetros);

Desarrollo de funciones miembro:


val_devuelto nomb_clase::nomb_funcion(parametros){
cuerpo;
}

EJEMPLO: Declaramos una clase con una variable privada y dos funciones públicas. La
clase recibe el nombre de miclase.
class miclase{
int a;
public:
void funcion1(int num);
int funcion2();
}

4. Mi Primer Programa

Capítulo anterior: 3 - Creación de Clases y Objetos


Capítulo siguiente: 5 - Entrada y Salada por Consola en C++

Como ejemplo a lo anterior crearemos el primer programa utilizando objetos y clases


para ver la teoría llevada a la práctica. Seguiremos utilizando las mismas sentencias que
usábamos en C, más adelante los programas tomarán la estructura exclusiva de C++.

#include <stdio.h>
#include <conio.h>

class miclase{
int a;
public:
void pasar_a(int num);
int mostrar_a();
};
void miclase::pasar_a(int num)
{
a=num;
}

int miclase::mostrar_a()
{
return a;
}

void main()
{
miclase obj1, obj2;
clrscr();
obj1.pasar_a(10);
obj2.pasar_a(99);
printf("%d\n",obj1.mostrar_a());
printf("%d\n",obj2.mostrar_a());
getch();
}

5. Entrada y Salada por Consola en C++

Capítulo anterior: 4 - Mi Primer Programa


Capítulo siguiente: 6 - Funciones Constructoras y Destructoras

En C++ se pueden seguir utilizando las mismas sentencias para mostrar información por
pantalla o pedirla mediante teclado. Pero a estas antiguas se añaden 2 nuevas de la
misma potencia y mayor facilidad de uso. La cabecera que utilizan estas dos sentencias
es iostream.h.

Mostrar por pantalla:


cout << expresión;

Pedir por teclado:


cin >> variable; La variable pude ser de cualquier tipo.

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>

void main()
{
int i,j;
double d;
clrscr();
i=10;
j=15;
cout <<"Introducir valor: ";
cin>>d;
cout << "Estos son los valores: ";
cout << i << " "<< j << " "<< d;
getch();
}

INDICADORES DE FORMATO: Tres funciones miembro (width, precision y fill)


que fijan formato de anchura, precisión y carácter de relleno. Es necesario fijar la
anchura, precisión y carácter de relleno antes de cada sentencia de escritura.
ANCHURA: cout.width(ancho);
DECIMALES: cout.precision(nº digitos);
RELLENO: cout.fill('carácter');

EJEMPLO:
#include<iostream.h>
#include<stdio.h>
#include<conio.h>

void main()
{
double numero=123.1234567;
clrscr();
cout<< "hola" <<"\n";
cout.width(15);
cout<< "hola" <<"\n";
cout.width(15);
cout.fill('*');
cout<< "hola"<<"\n";
cout<<numero <<"\n";
cout.precision(4);
cout<<numero <<"\n";
cout.precision(10);
cout<<numero;
getch();
}

MODIFICADORES DE LA CLASE IOS: Estos modificadores son pertenecientes a


la clase ios. Cuando se activan su valor se mantiene, es decir hay que desactivarlos para
volver al formato de salida original.

Fijar indicador:
cout.setf(ios::identificador|ios::identificador2);

Anular identificador:
cout.unsetf(ios::identificador|ios::identificador2);

IDENTIFICADOR DESCRIPCIÓN
oct Devuelve un entero en octal.
hex Devuelve un entero en hexadecimal.
scientific Devuelve un número en formato científico.
showpoint Muestra 6 decimales aunque no sea necesario
showpos Muestra el signo + en los valores positivos
left Ajusta la salida a la izquierda.
skipws Omite los espacios a la izquierda de la salida.
uppercase Muestra el texto en mayúsculas.

EJEMPLO:
#include <stdio.h>
#include <conio.h>
#include <iostream.h>
void main()
{
float num=200.0;
int num1=200;
clrscr();
cout<<num <<"\n";
cout.setf(ios::showpos|ios::showpoint);
cout<<num <<"\n";
cout.setf(ios::scientific);
cout<<num <<"\n";
cout.unsetf(ios::scientific|ios::showpoint|ios::showpos);
cout<<num <<"\n";
cout.setf(ios::hex);
cout<<num1 <<"\n";
getch();
}

6. Funciones Constructoras y Destructoras

Capítulo anterior: 5 - Entrada y Salada por Consola en C++


Capítulo siguiente: 7 - Funciones InLine y Automáticas

En los programas hay partes que requieren inicialización. Esta necesidad de


inicialización es incluso más común cuando se está trabajando con objetos. Para tratar
esta situación, C++ permite incluir una función constructora. A estas funciones se las
llama automáticamente cada vez que se crea un objeto de esa clase.

La función constructora debe tener el mismo nombre que la clase de la que es parte, no
tienen tipo devuelto, es ilegal que un constructor tenga un tipo devuelto. Pero si es
posible pasarle valores a modo de parámetros.

Prototipo de la función:
nombre_fucion(parámetros);
Desarrollo de la función:
nombre_calse::nombre_funcion(parámetros){
cuerpo;
}

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class miclase{
int a;
public:
miclase();
void show();
};

miclase::miclase()
{
a=100;
}

void miclase::show()
{
cout << a;
}

void main()
{
clrscr();
miclase obj;
obj.show();
getch();
}

El complemento de un constructor es la función destructora. A esta función se la llama


automáticamente cuando se destruye el objeto. El nombre de las funciones destructoras
debe ser el mismo que el de la clase a la que pertenece precedido del carácter ~
(alt+126). Los objetos de destruyen cuando se salen de ámbito cuando son locales y al
salir del programa si son globales. Las funciones destructoras no devuelve tipo y
tampoco pueden recibir parámetros.

Técnicamente un constructor y un destructor se utilizan para inicializar y destruir los


objetos, pero también se pueden utilizar para realizar cualquier otra operación. Sin
embargo esto se considera un estilo de programación pobre.

PROTOTIPO DE LA FUNCIÓN:
~nombre_funcion(parámetros);

DESARROLLO DE LA FUNCION:
nombre_clase::nombre_funcion(){
cuerpo;
}

EJEMPLO: Mismo programa de antes añadiendo una función destructora.


#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class miclase{
int a;
public:
miclase();
~miclase();
void show();
};

miclase::miclase()
{
a=100;
}

miclase::~miclase()
{
cout << "Destruyendo...\n";
getch();
}

void miclase::show()
{
cout << a;
}

void main()
{
clrscr();
miclase obj;
obj.show();
getch();
}

CONSTRUCTORES CON PARAMETROS: Es posible pasar argumentos a una


función constructora. Para permitir esto, simplemente añada los parámetros a la
declaración y definición de la función constructora. Después, cuando declare un objeto,
especifique los parámetros como argumentos.

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class miclase{
int a;
public:
miclase(int x);
void mostrar();
};

miclase::miclase(int x)
{
cout << "Constructor";
a=x;
}

void miclase::miclase()
{
cout <<"El valor de a es: ";
cout << a;
}

void main()
{
miclase objeto(4);
ob.show();
getch();
}

7. Funciones InLine y Automáticas

Capítulo anterior: 6 - Funciones Constructoras y Destructoras


Capítulo siguiente: 8 - Utilización de Estructuras como Clases

La ventaja de las funciones insertadas es que se pueden ejecutar más rápidamente que
las funciones normales. La llamada y vuelta de una función normal tardan tiempo y si
tienen parámetros incluso más. Para declarar este tipo de funciones simplemente hay
que preceder la definición de la función con el especificador inline.

inline valor_devuelto nombre_función(parámetros)


{
cuerpo;
}

Las llamadas a las funciones insertadas se realiza de la misma manera que cualquier
función. Uno de los requisitos es que se tiene que definir antes de llamarla, es decir
definir y desarrollar antes de la función main.

Si el compilador no es capaz de cumplir la petición, la función se compila como una


función normal y la solicitud inline se ignora. Las restricciones son cuatro, no puede
contener variables de tipo static, una sentencia de bucle, un switch o un goto.
EJEMPLO: En este programa utilizamos una función inline pasando valores. No usa
clases ni objetos.
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
inline int valor(int x) { return ¡!(X%2);}
void main()
{
int a;
cout <<"Introducir valor: ";
cin >> a;
if (valor(a))
cout << "Es par ";
else
cout << "Es impar";
}

La característica principal de las funciones automáticas es que su definición es lo


suficientemente corta y puede incluirse dentro de la declaración de la clase. La palabra
inline no es necesaria. Las restricciones que se aplican a las funciones inline se aplican
también para este tipo. El uso más común de las funciones automáticas es para
funciones constructoras.

valor_devuelto nombre_funcion(parametros){cuerpo;}

EJEMPLO: Mismo programa anterior pero sin utilizar inline.


#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class ejemplo{
public:
int valor(int x) { return ¡!(X%2);}
};

void main()
{
int a;
cout <<"Introducir valor: ";
cin >> a;
if (valor(a))
cout << "Es par ";
else
cout << "Es impar";
}

8. Utilización de Estructuras como Clases


Capítulo anterior: 7 - Funciones InLine y Automáticas
Capítulo siguiente: 9 - Operaciones con Objetos

En C++, la definición de una estructura se ha ampliado para que pueda también incluir
funciones miembro, incluyendo funciones constructoras y destructoras como una clase.
De hecho, la única diferencia entre una estructura y una clase es que, por omisión, los
miembros de una clase son privados y los miembros de una estructura son públicos.
struct nombre{
variables y funciones publicas;
private:
variables y funciones privadas;
};

Aunque las estructuras tienen las mismas capacidades que las clases, se reserva el uso
de struct para objetos que no tienen funciones miembro. Una de las razones de la
existencia de las estructuras es mantener compatibilidad con los programas hechos C.

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>
struct tipo{
tipo(double b, char *n);
void mostrar();
private:
double balance;
char nombre[40];
};

tipo::tipo(double b, char *n)


{
balance=b;
strcpy(nombre,n);
}

void tipo::mostrar()
{
cout << "Nombre: " << nombre;
cout << ": $" << balance;
if (balance<0.0) cout << "****";
cout << "\n";
}

void main()
{
clrscr();
tipo acc1(100.12,"Ricardo");
tipo acc2(-12.34,"Antonio");
acc1.mostrar();
getch();
clrscr();
acc2.mostrar();
getch();
}

9. Operaciones con Objetos

Capítulo anterior: 8 - Utilización de Estructuras como Clases


Capítulo siguiente: 10 - Funciones Amigas

ASIGNACIÓN DE OBJETOS: Se puede asignar un objeto a otro a condición de que


ambos objetos sean del mismo tipo (misma clase). Cuando un objeto se asigna a otro se
hace una copia a nivel de bits de todos los miembros, es decir se copian los contenidos
de todos los datos. Los objetos continúan siendo independientes.
objeto_destino=objeto_origen;

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class miclase{
int a,b;
public:
void obtener(int i, int j){a=i;b=j;}
void mostrar(){cout << a << " "<< b << "\n";}
};

void main()
{
miclase o1,o2;
o1.obtener(10,4);
o2=o1;
o1.show();
o2.show();
getch();
}

ARRAY DE OBJETOS: Los objetos son variables y tienen las mismas capacidades y
atributos que cualquier tipo de variables, por tanto es posible disponer objetos en un
array. La sintaxis es exactamente igual a la utilizada para declarar y acceder al array.
También disponemos de arrays bidimensionales.

DECLARACIÓN:
nombre_clase nombre_objeto[nº elementos];
nombre_clase nombre_objeto[nº elementos]={elementos};
INICIALIZACIÓN:
nombre_objeto[índice].función(valores);

EJEMPLO: Unidimensional.
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class ejemplo{
int a;
public:
void pasar(int x){a=x;}
int mostrar() {return a;}
};
void main()
{
ejemplo ob[4];
int indice;
clrscr();
for(indice=0;indice<4;indice++)
ob[indice].pasar(indice);
for(indice=0;indice<4;indice++)
{
cout << ob[indice].mostrar();
cout << "\n";
}
getch();
}

EJEMPLO: Bidimensional.
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class bidi{
int a,b;
public:
bidi(int n, int m){a=n;b=m;}
int pasa_a(){return a;}
int pasa_b(){return b;}
};
void main()
{
clrscr();
int fil,col;
bidi objeto[3][2]={
bidi(1,2),bidi(3,4),
bidi(5,6),bidi(7,8),
bidi(9,10),bidi(11,12)};
for(fil=0;fil<3;fil++)
{
for(col=0;col<2;col++)
{
cout << objeto[fil][col].pasa_a();
cout << " ";
cout << objeto[fil][col].pasa_b();
cout << "\n";
}
}
getch();
}

PASO DE OBJETOS A FUNCIONES: Los objetos se pueden pasar a funciones como


argumentos de la misma manera que se pasan otros tipos de datos. Hay que declarar el
parámetro como un tipo de clase y después usar un objeto de esa clase como argumento
cuando se llama a la función. Cuando se pasa un objeto a una función se hace una copia
de ese objeto.

Cuando se crea una copia de un objeto porque se usa como argumento para una función,
no se llama a la función constructora. Sin embargo, cuando la copia se destruye (al salir
de ámbito), se llama a la función destructora.

PROTOTIPO DE FUNCIÓN:
tipo_devuelto nombre(nombre_clase nombre_objeto){
cuerpo;
}

LLAMADA A LA FUNCIÓN:
nombre_funcion(objeto);

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class objetos{
int i;
public:
objetos(int n){i=n;}
int devol(){return i;}
};
int sqr(objetos o)
{
return o.devol()*o.devol();
}
void main()
{
objetos a(10), b(2);
cout << sqr(a);
cout << sqr(b);
getch();
}
OBJETOS DEVUELTOS POR FUCIONES: Al igual que se pueden pasar objetos, las
funciones pueden devolver objetos. Primero hay que declarar la función para que
devuelva un tipo de clase. Segundo hay que devolver un objeto de ese tipo usando la
sentencia return.

Cuando un objeto es devuelto por una función, se crea automáticamente un objeto


temporal que guarda el valor devuelto. Este es el objeto que realmente devuelve la
función. Después el objeto se destruye, esto puede causar efectos laterales inesperados.

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
class ejemplo{
char cadena[80];
public:
void muestra(){cout<<cadena<<"\n";}
void copia(char *cad){strcpy(cadena,cad);}
};
ejemplo entrada()
{
char cadena[80];
ejemplo str;
cout<<"Introducir cadena: ";
cin>>cadena;
str.copia(cadena);
return str;
}
void main()
{
ejemplo ob;
ob=entrada();
ob.muestra();
getch();
}

PUNTEROS A OBJETOS: Hasta ahora se ha accedido a miembros de un objeto


usando el operador punto. Es posible acceder a un miembro de un objeto a través de un
puntero a ese objeto. Cuando sea este el caso, se emplea el operador de flecha (->) en
vez del operador punto. Para obtener la dirección de un objeto, se precede al objeto con
el operador &. Se trabaja de igual forma que los punteros a otros tipos.

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class miclase{
int a;
public:
miclase(int x);
int get();
};
miclase::miclase(int x)
{
a=x;
}
int miclase::get()
{
return a;
}
void main()
{
clrscr();
miclase obj(200);
miclase *p;
p=&obj;
cout << "El valor del Objeto es " << obj.get();
cout << "El valor del Puntero es " << p->get();
getch();
}

10. Funciones Amigas

Capítulo anterior: 9 - Operaciones con Objetos


Capítulo siguiente: 11 - This, New y Delete

Habrá momentos en los que se quiera que una función tenga acceso a los miembros
privados de una clase sin que esa función sea realmente un miembro de esa clase. De
cara a esto están las funciones amigas. Son útiles para la sobrecarga de operadores y la
creación de ciertos tipos de funciones E/S.

El prototipo de esta funciones viene precedido por la palabra clave friend, cuando se
desarrolla la función no es necesario incluir friend. Una función amiga no es miembro
y no se puede calificar mediante un nombre de objeto. Estas funciones no se heredan y
pueden ser amigas de más de una clase.

PROTOTIPO:
friend tipo_devuelto nombre(parametros);

DESARROLLO:
tipo_devuelto nombre(parametros){
cuerpo;
}

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class miclase{
int n,d;
public:
miclase(int i, int j){n=i;d=j;}
friend int factor(miclase ob);
};

int factor(miclase ob)


{
if (!(ob.n%ob.d))
return 1;
else
return 0;
}

void main()
{
miclase obj1(10,2), obj2(3,2);
if(factor(obj1))
cout << "es factor";
else
cout << "no es factor";
getch();
}

11. This, New y Delete

Capítulo anterior: 10 - Funciones Amigas


Capítulo siguiente: 12 - Referencias

This es un puntero que se pasa automáticamente a cualquier miembro cuando se invoca.


Es un puntero al objeto que genera la llamada, por tanto la función recibe
automáticamente un puntero al objeto. A este puntero se referencia como this y solo se
pasa a los miembros punteros this.
objeto.funcion(); // a la función recibe automáticamente el puntero this.

EJEMPLO: El primero sin puntero this. El segundo utilizando el puntero this.

1.-
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
class stock{
char item[20];
double coste;
public:
stock(char *i,double c)
{
strcpy(item,i);
coste=c;
}
void muestra();
};

void stock::muestra()
{
cout<<item << "\n";
cout<<"PVP: " << coste;
}

void main()
{
clrscr();
stock obj("tuerca",5.94);
obj.muestra();
getch();
}

2.-
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
class stock{
char item[20];
double coste;
public:
stock(char *i,double c)
{
strcpy(this->item,i);
this->coste=c;
}
void muestra();
};

void stock::muestra()
{
cout<<this->item << "\n";
cout<<"PVP: " << this->coste;
}

void main()
{
clrscr();
stock obj("tuerca",5.94);
obj.muestra();
getch();
}

Hasta ahora si se necesitaba asignar memoria dinámica, se hacía con malloc y para
liberar se utilizaba free. En C++ se puede asignar memoria utilizando new y liberarse
mediante delete. Estas operadores no se pueden combinar unas con otras, es decir debe
llamarse a delete solo con un puntero obtenido mediante new. Los objetos también se
les puede pasar un valor inicial con la sentencia new.

SINTAXIS:
puntero=new tipo;
delete puntero;
puntero=new tipo(valor_inicial);

También se pueden crear arrays asignados dinámicamente, estos arrays pueden utilizar
la sentencia new. La sintaxis general es:

DECLARACION DEL ARRAY:


puntero=new tipo[tamaño];

EJEMPLO:
#include<iostream.h>
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
class cosas{
int i,j;
public:
void obten(int a,int b){i=a;j=b;}
int muestra(){return i*j;}
};
void main()
{
clrscr();
int *p_var;
p_var=new int;
//p_var=new int(9); se asigna un valor inicial.
cosas *p;
p=new cosas;
if(!p || !p_var)
{
cout<<"Error de asignacion\n";
exit(1);
}

*p_var=1000;
p->obten(4,5);
cout<<"El entero en p_var es: " <<*p_var;
cout<<"\nTotal: " <<p->muestra();
getch();
}

EJEMPLO: Array asignado dinámicamente.

#include<iostream.h>
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
void main(void)
{
int *p;
int i;
p=new int[5];
clrscr();
if(!p)
{
cout<<"Error de asignacion\n";
exit(1);
}
for(i=0;i<5;i++)
p[i]=i+1;
for(i=0;i<5;i++)
{
cout<<"Este es el entero en p["<<i<<"]:";
cout<<p[i]<<"\n";
}
delete[] p;
getch();
}

12. Referencias

Capítulo anterior: 11 - This, New y Delete


Capítulo siguiente: 13 - Herencia

C++ consta de una particularidad relacionada con los punteros, denominada referencia.
Una referencia es un puntero implícito que se comporta como una variable normal
siendo un puntero. Existen tres modos de utilizar una referencia. Se puede pasar a una
función, ser devuelta de una función y crearse como una referencia independiente. Lo
que apunta una referencia no puede ser modificado. El caso de las referencias
independientes es muy poco común y casi nunca se utilizan, en este manual no se hace
referencia a ellas.

En el ejemplo siguiente se compara un programa que utiliza un puntero normal y otro


programa que realiza las mismas operaciones utilizando una referencia que se pasa a
una función.
EJEMPLO:
Utilizando punteros normal.
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
void f(int *n);
void main()
{
int i=0;
f(&i);
cout<<"valor i:" << i;
getch();
}
void f(int *n)
{
*n=100;
}

Utilizando referencias.
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
void f(int &n);
void main()
{
int i=0;
f(i);
cout<<"valor i:"<< i;
getch();
}

void f(int &n)


{
n=100;
}

En el caso de las referencias devueltas por una función se puede poner el nombre de la
función en el lado izquierdo de la expresión. Es como asignar un valor a una variable.
Hay que tener en cuenta el ámbito de la variable que se comporta como una referencia.

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
int &f();
int x;
void main()
{
clrscr();
f()=100;
cout<<"Valor de x: " <<x;
getch();
}

int &f()
{
return x;
}

13. Herencia

Capítulo anterior: 12 - Referencias


Capítulo siguiente: 14 - Funciones Virtuales

Para empezar, es necesario definir dos términos normalmente usados al tratar la


herencia. Cuando una clase hereda otra, la clase que se hereda se llama clase base. La
clase que hereda se llama clase derivada. La clase base define todas las cualidades que
serán comunes a cualquier clase derivada. Otro punto importante es el acceso a la clase
base. El acceso a la clase base pude tomar 3 valores, public, private y protected.

Si el acceso es public, todos los atributos de la clase base son públicos para la derivada.

Si el acceso es private, los datos son privados para la clase base la derivada no tiene
acceso.

Si el acceso es protected, datos privados para la base y derivada tiene acceso, el resto
sin acceso.

EJEMPLO: para comprobar los distintos tipos de acceso.


#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class miclase{
int a;
protected:
int b;
public:
int c;
miclase(int n,int m){a=n;b=m;}
int obten_a(){return a;}
int obten_b(){return b;}
};

void main()
{
miclase objeto(10,20);
clrscr();
objeto.c=30;
// objeto.b=30; error,sin acceso.
// objeto.a=30; error,sin acceso.
cout<<objeto.obten_a() <<"\n";
cout<<objeto.obten_b() <<"\n";
cout<<objeto.c;
getch();
}

FORMATO DE LA CLASE DERIVADA:


class nombre_derivada:acceso nombre_base{
cuerpo;
};

EJEMPLO: Herencia pública.


#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class base{
int x;
public:
void obten_x(int a){x=a;}
void muestra_x(){cout<< x;}
};

class derivada:public base{


int y;
public:
void obten_y(int b){y=b;}
void muestra_y(){cout<<y;}
};

void main()
{
derivada obj;
clrscr();
obj.obten_x(10);
obj.obten_y(20);
obj.muestra_x();
cout<<"\n";
obj.muestra_y();
getch();
}

EJEMPLO: Herencia con acceso privado.


#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class base{
int x;
public:
void obten_x(int a){x=a;}
void muestra_x(){cout<<x <<"\n";}
};

class derivada:private base{


int y;
public:
void obten_xy(int a,int b){obten_x(a);y=b;}
void muestra_xy(){muestra_x();cout<<y<<"\n";}
};

void main()
{
clrscr();
derivada ob;
ob.obten_xy(10,20);
ob.muestra_xy();
// ob.obten_x(10); error,sin acceso.
// ob.muestra_x(); error,sin acceso.
getch();
}

HERENCIA MULTIPLE: Existen dos métodos en los que una clase derivada puede
heredar más de una clase base. El primero, en el que una clase derivada puede ser usada
como la clase base de otra clase derivada, creándose una jerarquía de clases. El
segundo, es que una clase derivada puede heredar directamente más de una clase base.
En esta situación se combinan dos o más clases base para facilitar la creación de la clase
derivada.

SINTAXIS: Para construir la derivada mediante varias clases base.


class derivada:acceso nomb_base1,nomb_base2,nomb_baseN{
cuerpo;
};

SINTAXIS: Para crear herencia múltiple de modo jerárquico.


class derivada1:acceso base{
cuerpo;
};

class derivada2:acceso derivada1{


cuerpo;
};

class derivadaN:acceso derivada2{


cuerpo;
};

EJEMPLO: Herencia de tipo jerárquica.


#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class base_a{
int a;
public:
base_a(int x){a=x;}
int ver_a(){return a;}
};

class deriva_b:public base_a{


int b;
public:
deriva_b(int x, int y):base_a(x){b=y;}
int ver_b(){return b;}
};

class deriva_c:public deriva_b{


int c;
public:
deriva_c(int x,int y,int z):deriva_b(x,y){c=z;}
void ver_todo()
{
cout<<ver_a()<<" "<<ver_b()<<" "<<c;
}
};

void main()
{
clrscr();
deriva_c ob(1,2,3);
ob.ver_todo();
cout<<"\n";
cout<<ob.ver_a()<<" "<<ob.ver_b();
getch();
}

El caso de los constructores es un poco especial. Se ejecutan en orden descendente, es


decir primero se realiza el constructor de la clase base y luego el de las derivadas. En las
destructoras ocurre en orden inverso, primero el de las derivadas y luego el de la base.

EJEMPLO: Múltiple heredando varias clases base.


#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class B1{
int a;
public:
B1(int x){a=x;}
int obten_a(){return a;}
};
class B2{
int b;
public:
B2(int x){b=x;}
int obten_b(){return b;}
};

class C1:public B1,public B2{


int c;
public:
C1(int x,int y,int z):B1(z),B2(y)
{
c=x;
}
void muestra()
{
cout<<obten_a()<<" "<<obten_b()<<" ";
cout<<c<<"\n";
}
};

void main()
{
clrscr();
C1 objeto(1,2,3);
objeto.muestra();
getch();
}

14. Funciones Virtuales

Capítulo anterior: 13 - Herencia


Capítulo siguiente: 15 - Sobrecarga de Funciones y Operadores

Una función virtual es miembro de una clase que se declara dentro de una clase base y
se redefine en una clase derivada. Para crear una función virutal hay que preceder a la
declaración de la función la palabra clave virtual. Debe tener el mismo tipo y numero de
parametros y devolver el mismo tipo.

Cada redefinición de la función virtual en una clase derivada expresa el funcionamiento


especifico de la misma con respecto a esa clase derivada. Cuando se redefine una
función virtual en una clase derivada NO es necesaria la palabra virtual.

EJEMPLO:
#include<iostream.h>
#include<stdio.h>
#include<conio.h>
class base{
public:
int i;
base(int x){i=x;}
virtual void func(){cout<<i<<"\n";}
};

class derivada1:public base{


public:
derivada1(int x):base(x){};
void func(){ cout <<i*i<<"\n";}
};

class derivada2:public base{


public:
derivada2(int x):base(x){};
void func(){cout<<i+i;}
};

void main()
{
base obj1(10);
derivada1 obj2(10);
derivada2 obj3(10);
obj1.func();
obj2.func();
obj3.func();
getch();
}

15. Sobrecarga de Funciones y Operadores

Capítulo anterior: 14 - Funciones Virtuales


Capítulo siguiente: 16 - Ficheros

En C++ dos o más funciones pueden compartir el mismo nombre en tanto en cuanto
difiera el tipo de sus argumentos o el número de sus argumentos o ambos. Cuando
comparten el mismo nombre y realizan operaciones distintas se dice que están
sobrecargadas. Para conseguir la sobrecarga simplemente hay que declarar y definir
todas las versiones requeridas.

También es posible y es muy común sobrecargar las funciones constructoras. Hay 3


razones por las que sobrecargar las funciones constructoras. Primero ganar flexibilidad,
permitir arrays y construir copias de constructores.

EJEMPLO:
#include <iostream.h>
#include <conio.h>
#include <stdio.h>
int abs(int numero);
long abs(long numero);
double abs(double numero);

void main()
{
clrscr();
cout <<"Valor absoluto de -10 "<< abs(-10) <<"\n";
cout <<"Valor absoluto de -10L "<< abs(-10L) <<"\n";
cout <<"Valor absoluto de -10.01 "<< abs(-10.01) <<"\n";
getch();
}

int abs(int numero)


{
return numero<0 ? -numero:numero;
}
long abs(long numero)
{
return numero<0 ? -numero:numero;
}
double abs(double numero)
{
return numero<0 ? -numero:numero;
}

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
void fecha(char *fecha);
void fecha(int anno, int mes, int dia);
void main()
{
clrscr();
fecha("23/8/98");
fecha(98,8,23);
getch();
}
void fecha(char *fecha)
{
cout<<"Fecha: "<<fecha<<"\n";
}
void fecha(int anno,int mes,int dia)
{
cout<<"Fecha: "<<dia<<"/"<<mes<<"/"<<anno;
}
ARGUMENTOS IMPLICITOS: Otra característica relacionada con la sobrecarga es
la utilización de argumentos implícitos que permite dar un valor a un parámetro cuando
no se especifica el argumento correspondiente en la llamada a la función.

PROTOTIPO:
tipo_devuelto(var1=valor,var2=valor,varN=valor);

EJEMPLO:
#include<iostream.h>
#include<stdio.h>
#include<conio.h>
void funcion(int a=0, int b=0)
{
cout<<"a: "<< a <<" b: "<< b <<"\n";
}

void main()
{
clrscr();
funcion();
funcion(10);
funcion(20,30);
getch();
}

Es muy similar a la sobrecarga de funciones, un operador siempre se sobrecarga con


relación a una clase. Cuando se sobrecarga un operador no pierde su contenido original,
gana un contenido relacionado con la clase. Para sobrecargar un operador se crea una
función operadora que normalmente será una función amiga a la clase.

PROTOTIPO:
tipo_devuelto nombre_clase::operator operador(parametros)
{
cuerpo;
}

Se pueden realizar cualquier actividad al sobrecargar los operadores pero es mejor que
las acciones de un operador sobrecargado se ajusten al uso normal de ese operador. La
sobrecarga tiene dos restricciones, no puede cambiar la precedencia del operador y que
el numero de operadores no puede modificarse. También hay operadores que no pueden
sobrecargarse.

OPERADORES
.
::
¿??
.*
Existen 3 tipos de sobrecarga de operadores. Operadores binarios, operadores logicos-
relacionales y operadores unarios. Cada uno de ellos deben tratarse de una manera
especifica para cada uno de ellos.

BINARIOS: La función solo tendrá un parametro. Este parámetro contendrá al objeto


que este en el lado derecho del operador. El objeto del lado izquierdo es el que genera la
llamada a la función operadora y se pasa implícitamente a través de this.

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class opera{
int x, y;
public:
opera() {x=0;y=0;}
opera(int i, int j) {x=i; y=j;}
void obtenxy(int &i,int &j) {i=x; j=y;}
opera operator+(opera obj);
};

opera opera::operator+(opera obj)


{
opera temp;
temp.x=x+obj.x;
temp.y=y+obj.y;
return temp;
}

void main()
{
opera obj1(10,10), obj2(5,3),obj3;
int x,y;
obj3=obj1+obj2;
obj3.obtenxy(x,y);
cout << "Suma de obj1 mas obj2\n ";
cout << "Valor de x: "<< x << " Valor de y: " << y;
getch();
}

LÓGICOS Y RELACIONALES: Cuando se sobrecargan dichos operadores no se


deseará que las funciones operadoras devuelvan un objeto, en lugar de ello, devolverán
un entero que indique verdadero o falso. Esto permite que los operadores se integren en
expresiones lógicas y relacionales más extensas que admitan otros tipos de datos.

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class opera{
int x,y;
public:
opera() {x=0;y=0;}
opera(int i,int j) {x=i; y=j;}
void obtenerxy(int &i, int &j) {i=x; j=y;}
int operator==(opera obj);
};

int opera::operator==(opera obj)


{
if(x==obj.x && y==obj.y)
return 1;
else
return 0;
}

void main()
{
clrscr();
opera obj1(10,10), obj2(5,3);
if(obj1==obj2)
cout << "Objeto 1 y Objeto 2 son iguales";
else
cout << " Objeto 1 y objeto 2 son diferentes";
getch();
}

UNARIOS: El miembro no tiene parámetro. Es el operando el que genera la llamada a


la función operadora. Los operadores unarios pueden preceder o seguir a su operando,
con lo que hay que tener en cuenta como se realiza la llamada.

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class opera{
int x, y;
public:
opera() {x=0;y=0;}
opera(int i, int j) {x=i;y=j;}
void obtenxy(int &i, int &j) {i=x; j=y;}
opera operator++();
};

opera opera::operator++()
{
x++;
y++;
}
void main()
{
clrscr();
opera objeto(10,7);
int x,y;
objeto++;
objeto.obtenxy(x,y);
cout<< "Valor de x: " << x <<" Valor de y: "<< y << "\n";
getch();
}

¡Te informamos cada semana de los nuevos cursos gratuitos

16. Ficheros

Capítulo anterior: 15 - Sobrecarga de Funciones y Operadores


Capítulo siguiente: 17 - Excepciones

Para realizar E/S en archivos debe incluirse en el programa el archivo cabecera


fstream.h. Un archivo se abre mediante el enlace a un flujo. Tenemos 3 tipos de flujo:
de entrada, de salida o de entrada-salida. Antes de abrir un fichero debe obtenerse el
flujo. Los 3 flujos tienen funciones constructoras que abren el archivo automáticamente.
Una vez realizadas las operaciones con los ficheros debemos cerrar el fichero mediante
la función close( ).

FLUJO DESCRIPCIÓN
ofstream out De salida.
ofstream in De entrada.
fstream io De salida-entrada.

En C++ podemos trabajar con 3 tipos de ficheros: secuencial, binario sin formato y
acceso aleatorio. Todos comparten el método de apertura, pero cada uno de ellos tienen
métodos propios para ir escribiendo y leyendo.

SINTAXIS:
flujo("nombre_fichero.extension");

EJEMPLO: Fichero secuencial.


#include <iostream.h>
#include <fstream.h>
#include <stdio.h>
#include <stdlib.h>
void main()
{
ofstream out("fichero.tex");
if (!out)
{
cout << "El archivo no puede abrirse";
exit(1);
}

char cad[80];
cout << "Escritura de cadenas. Salir dejar en blanco\n";

do
{
cout<<": ";
gets(cad);
out << cad << endl;
}while(*cad);

out.close();
}

BINARIOS SIN FORMATO: Las funciones E/S son read()y write(). La función read()
lee num bytes del flujo asociado y los coloca en la variable. La función write() escribe
num bytes de la variable en el flujo asociado.

PROTOTIPOS:
in.read(variable,num_bytes);
out.write(variable,longitud_cadena);

EJEMPLO: Fichero binario. Escritura.


#include <iostream.h>
#include <fstream.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
ofstream out("texto.tex");
if (!out)
{
cout << "El archivo no puede abrirse";
exit(1);
}

char cad[80];
cout << "Escritura de cadenas. Salir dejar en blanco\n";
do
{
cout<<": ";
gets(cad);
out.write(cad,strlen(cad));
}while(strlen(cad));
out.close();
}

EJEMPLO: Fichero binario. Lectura.


#include <iostream.h>
#include <fstream.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
void main()
{
clrscr();
ifstream in("texto.tex");
if (!in)
{
cout << "El archivo no puede abrirse";
exit(1);
}
char cad[80];
cout << "Lectura de cadenas\n";
in.read(cad,80);
cout << cad;

in.close();
getch();
}

ALEATORIOS: También podemos realizar el acceso aleatorio. Las funciones que se


utilizan son seekg() y seekp() para posicionarnos y las funciones get() y put() para leer y
escribir en el fichero. Las funciones de posicionamiento y leer-escribir van emparejadas.

PROTOTIPOS:
out.seekp(posicion,lugar_de_comienzo);
out.put('char');
in.seekg(posicion,lugar_de_comienzo);
in.get(var_char);

LUGAR DESCRIPCIÓN
ios::beg Desde el principio.
ios::end Desde el final.
ios::cur Posición actual.

EJEMPLO: Fichero aleatorio. Escritura.


#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
void main()
{
fstream out("texto1.txt",ios::in|ios::out);
if (!out)
{
cout << "El archivo no se puede abrir";
exit(1);
}
out.seekp(4,ios::beg);
out.put('z');
out.close();
}

17. Excepciones

Capítulo anterior: 16 - Ficheros

Es un mecanismo de gestión de errores incorporado. Permite gestionar y responder a los


errores en tiempo de ejecución. Las excepciones están construidas a partir de tres
palabras clave: try, catch y throw. Cualquier sentencia que provoque una excepción
debe haber sido ejecutada desde un bloque try o desde una función que este dentro del
bloque try.

Cualquier excepción debe ser capturada por una sentencia cath que sigue a la sentencia
try, causante de la excepción.

SINTAXIS:
try{
cuerpo;
}

catch(tipo1 arg){
bloque catch;
}

catch(tipo2 arg){
bloque catch;
}

catch(tipoN arg){
bloque catch;
}

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
void main()
{
try{
cout<<"Dentro del bloque try\n";
throw 10;
cout<<"Esto se ejecuta si no hay problemas";
}

catch(int i){
cout<<"Capturado el error "<< i;
cout<<"\n";
}

cout << "fin";


getch();
}

También podría gustarte