Tema 2: Elementos del C++ no
Orientados a Objetos
1 Tema 2: Elementos C++ no POO
Índice
1. Elementos avanzados del lenguaje C++ no POO
2. Punteros.
3. Gestión dinámica de la memoria
2 Tema 2: Elementos C++ no POO
Elementos avanzados del lenguaje C++ no
POO
Introducido el curso Pasado
Procedural (como C, Pascal, etc.)
Desarrollaremos en este tema
algunos elementos avanzados
Lenguaje
C++
Orientado a Objetos (como Java, Delphi, etc.)
(POO)
Introducido en los siguientes
temas
3 Tema 2: Elementos C++ no POO
Elementos avanzados del lenguaje C++ no POO
Operador de alcance ::
Para distinguir entre una variable global y una local con
el mismo nombre, colocamos :: delante de la variable
global. Hay otro uso en clases, se verá más adelante
#include <iostream>
using namespace std;
int count =50;
int main()
{
int count;
for(count=1; count<10; count++)
{
cout << “Result” << ::count/count << endl;
}
return(0);
} global local
4 Tema 2: Elementos C++ no POO
Elementos avanzados del lenguaje C++ no POO
Funciones en línea (inline): inline int calc(int a, int b)
Se especifica colocando el {
modificar inline delante de la return ( a/2 + b/3 ) % 5;
cabecera de la función }
int main ( )
Se insertan copias del código de
{
la función durante la int x, y, z;
compilación, en el lugar de la ...
llamadas a la función. z = calc( x, y );
El beneficio que ofrece es un cout << calc( z, x ) ;
}
aumento de la eficiencia al evitar
el coste que conlleva el pase de
parámetros y la llamada a la Se convierte en:
función. ...
Se trata de una solicitud al z = ( x/2 + y/3 ) % 5;
compilador, no hay garantía de cout << ( z/2 + x/3 ) % 5;
que se produzca la conversión. }
5 Tema 2: Elementos C++ no POO
Elementos avanzados del lenguaje C++ no POO
Sobrecarga de funciones:
C++ permite crear funciones con el mismo nombre y distintos tipos
o número de parámetros. Para el compilador son funciones
distintas
El compilador averigua a qué función se está invocando al
comparar los argumentos que se le pasan a la función con las
listas de parámetros de las diferentes funciones sobrecargadas.
int square() {return (2*2);}
int square(int x) {return (x*x);}
double square(double y){return (y*y);}
int square(int x, int y){return x*y;}
void main()
{
cout << "El cuadrado del entero 2 es:" << square();
cout << "El cuadrado del entero 7 es:" << square(7);
cout << "El cuadrado del double 7.5 es:" << square(7.5);
cout << "El producto de 7 y 8 es:" << square(7,8);
}
6 Tema 2: Elementos C++ no POO
Elementos avanzados del lenguaje C++ no POO
Argumentos por defecto:
Se pueden proporcionar valores por defecto a los parámetros
de una función cuando se define.
void muestracadena(string str="Hola Mundo!");
int main()
{
muestracadena("Texto a mostrar\n");
//Mostrará nuestro texto
muestracadena(); //Mostrará el texto por defecto.
return(0);
}
void muestracadena(string str)
{
cout << str << endl;
}
Cuando hay varios parámetros, si el parámetro k está definido
por defecto, el parámetro k+1 también tiene que estarlo:
void f ( int i , int x=2 , int y=2) ; // correcto
void f ( int i , int x=2 , int y ) ; // incorrecto
7 Tema 2: Elementos C++ no POO
Elementos avanzados del lenguaje C++ no POO
Calificador const:
Modificador de una variable que hace que esta no
pueda ser modificada. Es necesario inicializarla. Es la
forma de definir una constante en C++ (ej: PI).
const float PI=3.14;
void main( ) {
float rad = 3;
float a = CalculaArea(rad);
……
}
void CalculaArea(const float &r)
{
return PI * r * r;
}
8 Tema 2: Elementos C++ no POO
Elementos avanzados del lenguaje C++ no POO
Calificador const:
Usado sobre parámetros de la función no permite su
modificación, se utiliza con parámetros de los que solo
necesitamos su valor
void main( ) {
int vec[10];
LeeVector(vec);
MuestraVector(vec)
}
void LeeVector (int v[])
{
for(int i=0; i<10; i++) Si pusiéramos esta
cin >> v[i];
}
instrucción en la función
void MuestraVector(const int v[]) MuestraVector(…) daría
{ error.
for(int i=0; i<10; i++)
cout << v[i]; cin >> v[i]; //error
}
9 Tema 2: Elementos C++ no POO
Índice
1. Elementos avanzados del lenguaje C++ no POO
2. Punteros.
3. Gestión dinámica de la memoria
10 Tema 2: Elementos C++ no POO
Punteros
Introducción (1)
Elemento avanzado del Lenguaje C++ (no POO)
Heredado del lenguaje C
En dicho lenguaje se empleaba para emular el paso por
referencia
En C++ se utiliza sobre todo para trabajar con variables
dinámicas
11 Tema 2: Elementos C++ no POO
Punteros
Introducción (2)
Variables estáticas
Todas las variables estudiadas hasta el
momento.
Memoria reservada en tiempo de compilación.
Su valor cambia en tiempo de ejecución pero su
tamaño NO.
Ejemplo: programa que opere con vectores
Problemas de sobredimensionamiento.
Problemas de Infradimensionamiento.
¿Sólución?
12 Tema 2: Elementos C++ no POO
Punteros
Introducción (3)
Variables Dinámicas
Variables creadas en tiempo de ejecución.
Su tamaño se define en tiempo de ejecución.
Gestión de la memoria flexible y eficiente.
Estas variables guardan datos en memoria del
tipo de dato al que se han creado pero NO
tienen asignado un identificador.
¿Cómo operar con ellas?
Solución: Punteros.
13 Tema 2: Elementos C++ no POO
Punteros
Definición de Puntero
Un puntero es una variable estática, sirve para
almacenar la dirección de memoria donde se guarda
información dinámica del programa.
Se dice que el puntero apunta a la posición de
memoria que almacena en su interior.
Puntero Variable dinámica
pi dirección
valor memoria
1000 5 1000
14 Tema 2: Elementos C++ no POO
Punteros
Declaración de variables punteros en C++:
typedef int *PuntEntero;
PuntEntero p;
O directamente:
Hay que saber el
int *p;
tamaño de cada
dato que vamos
Siempre lleva asociado un tipo. ¿Por qué? a almacenar en
int *pi; ... memoria
El tipo de dato al que apunta el puntero (en el ejemplo
int) se denomina tipo base del puntero.
dirección
pi valor memoria
3FA04 33 3FA04
No podemos asignar un valor directamente a un puntero pi = 3;
15 Tema 2: Elementos C++ no POO
Punteros
OPERACIONES del tipo de dato Puntero
El puntero es un tipo de dato simple.
Dominio + Representación + ¿Operaciones?
Dirección (en C++): el operador & permite obtener la dirección de
una variable p x
int *p, x = 5; 5
p = &x;
Indirección (*) sobre un puntero, indica el contenido de la dirección
a la que apunta ¡Cuidado: no confundir con la definición del puntero!
cout << *p;// por pantalla 5
*p = 3;//cambia el valor de x a 3
p x
Asignación de punteros (=)
int *p2 = NULL;//Neutro puntero 3
p2 = p;
Comparación de punteros (==, !=) p2
if (p1 == p2) ...
16 Tema 2: Elementos C++ no POO
Punteros
¿Utilidad de los punteros?
Utilidad Punto 3 del tema Sobre todo en el lenguaje C
Variables dinámicas
Emular el paso por referencia void inc(int *pi)
{
• El parámetro de la función es un *pi = *pi + 1;
}
puntero que apunta a la variable
que se pasa como argumento. int main()
Dentro del subprograma se {
realizan las modificaciones sobre int i;
la variable a través del puntero. i = 2;
inc(&i);
• Para obtener la dirección de una cout << i;
variable, se utiliza el operador &. return 0;
}
17 Tema 2: Elementos C++ no POO
Punteros
Ejemplo parámetros de funciones de tipo puntero
void Intercambio (int *pa, int *pb)
{
int temp;
temp = *pa; void main() {
*pa = *pb; int x = 1, y = 2;
*pb = temp; Intercambio(&x, &y);
} }
pa
x
pb 1
Ámbito de Ámbito de
Intercambio y main
temp 2
18 Tema 2: Elementos C++ no POO
Punteros
Ejemplo parámetros de funciones de tipo puntero
void Intercambio (int *pa, int *pb)
{
int temp;
temp = *pa; void main() {
*pa = *pb; int x = 1, y = 2;
*pb = temp; Intercambio(&x, &y);
} }
pa
x
pb 1
Ámbito de Ámbito de
Intercambio y main
temp 2
1
19 Tema 2: Elementos C++ no POO
Punteros
Ejemplo parámetros de funciones de tipo puntero
void Intercambio (int *pa, int *pb)
{
int temp;
temp = *pa; void main() {
*pa = *pb; int x = 1, y = 2;
*pb = temp; Intercambio(&x, &y);
} }
pa
x
pb 2
Ámbito de Ámbito de
Intercambio y main
temp 2
1
20 Tema 2: Elementos C++ no POO
Punteros
Ejemplo parámetros de funciones de tipo puntero
void Intercambio (int *pa, int *pb)
{
int temp;
temp = *pa; void main() {
*pa = *pb; int x = 1, y = 2;
*pb = temp; Intercambio(&x, &y);
} }
pa
x
pb 2
Ámbito de Ámbito de
Intercambio y main
temp 1
1
21 Tema 2: Elementos C++ no POO
Crear una función que calcule la división entera,
devolviendo el cociente y el resto, usando punteros.
Primero lo haremos con un paso por referencia normal
en C++ y luego con punteros.
Ejercicio
22 Tema 2: Elementos C++ no POO
Índice
1. Elementos avanzados del lenguaje C++ no POO
2. Punteros.
3. Gestión dinámica de la memoria
23 Tema 2: Elementos C++ no POO
Gestión dinámica de la memoria
Reserva dinámica de memoria
Utilidad de los punteros? variables creadas dinámicamente.
El identificador que nos permite trabajar con los datos es el puntero.
En C++, las variables dinámicas se crean con el operador new.
new TipoBase : Crea una variable dinámica del tipo TipoBase. Devuelve
como resultado la dirección en memoria de la memoria reservada. Esta
dirección se deberá asignar a un puntero. A partir del puntero accedemos a
la información que habrá en la memoria que hemos reservado.
int *pi; pi
¿?
pi
pi = new int;
¿?
pi
*pi = 5; 5
24 Tema 2: Elementos C++ no POO
Gestión dinámica de la memoria
Liberación dinámica de la memoria
Cuando ya no son precisas las variables dinámicas se eliminan
Toda memoria reservada dinámicamente debe ser posteriormente
liberada cuando ya ha dejado de ser útil.
Si creamos una variable dinámica en un módulo y no la liberamos, al acabar
el módulo no se libera la memoria, queda bloqueada hasta que apaguemos
el ordenador. Tiempo de vida.
En C++, se libera la memoria de una variable dinámica con el
operador delete
pi
5
cout << *pi;
pi
delete pi; ¿?
¿Es útil crear dinámicamente variables simples?
¿Cómo se crean variables de tipos estructurados (vector, matriz)?
25 Tema 2: Elementos C++ no POO
Gestión dinámica de la memoria
Vectores dinámicos
Es MUY útil crear arrays dinámicamente.
En C++, se crean vectores dinámicos con el operador new
TipoBase[ n], dentro del corchete se indica el número de
elementos que quiero que reserve del tipo indicado
int n; cin >> n; // primero se lee el número de
elementos del vector
int * pi;
¿?
pi
pi = new int[n];
¿? ¿? ¿? ¿?
La reserva se hace de forma continua en
memoria
26 Tema 2: Elementos C++ no POO
Gestión dinámica de la memoria
Vectores dinámicos
Se accede a los elementos con el operador indexación [ ],
igual que si fuera un vector estático. Como nombre del
vector se usa el nombre de la variable puntero.
pi[0]=3; pi[2]=5;
El nombre de un vector estático, sin corchetes, indica la
dirección donde comienza la estructura (es un puntero
constante).
La memoria se libera con el operador delete [ ]puntero
pi
3 4 5 ¿?
pi
delete []pi;
¿?
27 Tema 2: Elementos C++ no POO
Gestión dinámica de la memoria
Ejemplo
int *vector; //Defino un puntero a entero
vector = new int[3]; //Reserva memoria para 3 enteros
//Accedo a los elemementos del array
vector[0]=8; vector[1]=925; vector[2]=46;
..............
//Libera la memoria cuando ya no se necesita
delete []vector;
Equivaldría a int vector[3] con memoria estática, y se maneja de igual forma.
28 Tema 2: Elementos C++ no POO
Realizar un programa que permita leer y escribir un
vector de números reales, cuyo tamaño lo introducirá el
usuario por teclado (usaremos reserva dinámica de
memoria). Se creará una función que lea el vector y
Ejercicio
otra para escribirla.
Programa que calcula la suma de dos vectores reales
en el que la dimensión y los valores del vector los
introduce el usuario por teclado. (tarea en aulavirtual)
29 Tema 2: Elementos C++ no POO
Gestión dinámica de la memoria
Matrices dinámicas
Vamos a utilizar el puntero a puntero. Como interpretarlo:
int **matriz;
si int *, es un puntero a entero.
Entonces int **, es un puntero a puntero a entero, almacena la
dirección de un vector de punteros a entero
int *(*matriz).
Se puede decir es un puntero a un vector dinámico de punteros.
Vector
30 Tema 2: Elementos C++ no POO
Gestión dinámica de la memoria
Matrices dinámicas
Array dinámico de dos dimensiones:
int **matriz; //vamos a crear una matriz nxm
matriz=new int *[n]; //Crea un vector de n punteros
for (int i=0;i<n;i++)
matriz[i]= new int[m]; //Crea vectores de m enteros
matriz[0][0]=10; //Accedemos a los elementos de la matriz
........... //delete se hace en orden inverso al new
for (int i=0;i<n;i++)
delete []matriz[i]; //Libera mem. de vectores de enteros
delete []matriz; //Libera memoria del vector de punteros
Equivaldría a int matriz[2][4] con memoria estática
matriz[0] matriz[0][0] matriz[0][1] matriz[0][2] matriz[0][3]
matriz
int ** int * int int int int
Vectores
de enteros
int * int int int int
Puntero Vector de
matriz[1] matriz[1][0] matriz[1][1] matriz[1][2] matriz[1][3]
a puntero punteros
a enteros
31 Tema 2: Elementos C++ no POO
Realizar un programa que permita buscar un elemento
en una matriz de dimensiones fijadas por el usuario, las
dimensiones las introducirá el usuario por teclado, el
programa deberá indicar cuantas veces aparece el
Ejercicio
valor en la matriz (usaremos reserva dinámica de
memoria).
Realiza un programa que suma las componentes de
una matriz dinámica, el usuario introducirá la dimensión
y el valor de sus componentes.
32 Tema 2: Elementos C++ no POO
Gestión dinámica de la memoria
Estructuras dinámicas
También se pueden crearp variables dinámicas que
sean estructuras: 3.1 7.5
struct Complejo int main() {
{ PtrCompl p;//Complejo *p
float re; p = new Complejo;
float im; (*p).re = 3.1;
}; (*p).im = 7.5;
typedef Complejo *PtrCompl; delete p;
}
Para simplificar el uso de los punteros a estructuras, en C++
existe un operador adicional para acceder a los campos:
p->re = 3.1;
p->im = 7.5;
33 Tema 2: Elementos C++ no POO
Realizar un programa que permita sumar las
componentes de un vector de números complejos, la
dimensión del vector la fijará el usuario.
Ejercicio
Cuando trabajamos con un vector y utilizamos los
corchetes, trabajaremos como un vector normal, sin la
flecha.
34 Tema 2: Elementos C++ no POO
Gestión dinámica de la memoria
Estructuras dinámicas recursivas/autoreferenciadas
Caso especial de estructuras dinámicas
Son estructuras con algún campo de tipo puntero a la propia
estructura: struct Nodo{
int numero; Puntero a un
Nodo * sig; dato de tipo
}; Nodo
Con estas estructuras se pueden crear tipos de datos muy
avanzados.
Por ejemplo, se pueden crear listas:
p 3 7 NULL
35 Tema 2: Elementos C++ no POO
Gestión dinámica de la memoria
Errores frecuentes (1)
1. No se debe utilizar el puntero antes de crear la variable
dinámica.
No olvidar reservar memoria antes de utilizar el puntero.
Todo puntero ha de apuntar a una dirección de memoria reservada
para ser usada por ese tipo de puntero, o si no, asignarle el valor
NULL. Es una buena práctica inicializar el puntero con el valor NULL.
2. No se debe utilizar el puntero después de liberar la memoria
de la variable dinámica.
3. No confundir el valor del puntero (dirección de memoria) con
el valor que contiene la memoria a la que apunta (del tipo del
puntero)
No confundir la asignación de punteros (p = q) con la asignación de
contenidos
(*p = *q).
36 Tema 2: Elementos C++ no POO
Gestión dinámica de la memoria
Errores frecuentes (2)
No confundir p = q; con *p = *q;
p
int *p, *q;
2
p = new int;
*p = 2; q
q = new int;
*q = 5; 5
p = q; *p = *q;
p p
2 5
q q
5 5
37 Tema 2: Elementos C++ no POO
Gestión dinámica de la memoria
Ejemplo (1)
typedef int * Vector;
void main() {
Vector v1; int *v2, *vr;
int tam;
cout << "Introduce el tamaño del vector:";
cin >> tam;
v1 = new int[tam];
v2 = new int[tam];
vr = new int[tam];
cout << "Introduce el primer vector:" << endl;
LeerVector(v1, tam);
cout << "Introduce el segundo vector:" << endl;
LeerVector(v2, tam);
SumarVector(v1, v2, vr, tam);
cout << "El vector suma es:" << endl;
MostrarVector(vr, tam);
delete [] v1;
delete [] v2;
38 delete [] vr;
}
Gestión dinámica de la memoria
Ejemplo (2)
void MostrarVector(Vector v, int tam)
{
for(int i = 0; i < tam; i++)
cout << v[i] << " ";
cout << endl;
}
void LeerVector(Vector v, int tam)
{
for(int i = 0; i < tam; i++)
cin >> v[i];
}
void SumarVector(const Vector v1, const Vector v2,
Vector vr, int tam)
{
for(int i = 0; i < tam; i++)
vr[i] = v1[i] + v2[i];
}
39 Asig.: Ampliación de Informática Mariano Pérez
Realizar un programa que permita la ordenación por
inserción de un vector de cualquier tamaño, el tamaño
lo introducirá el usuario por teclado (usaremos reserva
dinámica de memoria).(tarea de aulavirtual)
Ejercicio
40 Tema 2: Elementos C++ no POO