Tema 1: Organización de la memoria.
Tipos Abstractos de Datos.
Contenidos
1. Breve repaso de C
- Punteros.
- Recursividad.
- Modificadores
extern
,static
,volatile
. Guarda de ficheros
.h
:#ifndef XXX_H #define XXX_H /* Código C */ #endif
Puedes ver en este enlace un ejemplo de lo que tarda en compilar un proyecto real (LibreOffice) escrito en su mayoría en
C++
. Imagina si estuviera plagado deincludes
gratuitos!
2. El lenguaje de programación C++
2.1. Historia
- Comienza su desarrollo en 1979.
- Inicialmente se llamaba C con clases.
- El 14 de octubre de 1985 se publica cfront
1.0
, aquí puedes ver su código fuente y aquí puedes leer un artículo donde su creador (Bjarne Stroustrup) habla de los orígenes del lenguaje. - Curiosamente
cfront
era un traductor deC++
aC
.
2.2. Importante
- Es una extensión (más) orientada a objetos de
C
. - Trata de ser compatible con
C
(pero no todo programa enC
es un programa correcto enC++
). - Toma ideas del lenguaje Simula.
- Los principios en los que se basa son los de eficiencia y flexibilidad.
- Además de la POO añade más paradigmas como el de la programación genérica.
- Para conocer mejor la historia del origen de
C++
es recomendable que leas estos dos artículos.
2.3. Características añadidas a C
- Clases y objetos.
- Espacios de nombres.
- Constructores, destructores y funciones amigas.
- Zonas de visibilidad (
public
,private
yprotected
). - Operador de resolución de ámbito ( :: ).
- Funciones inline.
- Referencias (&).
- Entrada/Salida mejorada.
- Sobrecarga de funciones (mangling) y de operadores.
- Genericidad de funciones y de clases.
- Herencia (simple y múltiple), funciones virtuales.
- Nombres de operadores lógicos:
and
,or
,not
,xor
, etc…, además de los que ya conoces de C (&&
,||
,!
,^
…). - Literal puntero nulo :
nullptr
- Evaluación de expresiones en tiempo de compilación: constexpr.
- Antes de usar (llamar) una función el compilador debe conocer su prototipo o su definición.
- Valores por defecto en parámetros de funciones.
- No necesitaremos
typedef
de struct o class. - Tipo cadena. Es una clase de la biblioteca estándar de C++, no es un tipo base del lenguaje.
- Excepciones para el tratamiento de errores.
2.4. Ejemplo de-todo-un-poco
class TDerived : public TBase1, private TBase2, protected TBase3 { public: // Parte publica --------------------------------------------- TDerived (int a, std::string s = "") : TBase1 (a) , _s(s) { this->_a = a; _n++; } // constructor ~TDerived () { _s = ""; } // destructor inline bool isOk () { return (_s != ""); } // inline explícito bool isOk (const std::string& s) { // inline implícito if (not checkMe ()) return false; // acceso a la parte privada, nombres de op. return (_s != s); // acceso a la parte privada } static int howMany () { return _n; } // método de clase friend std::ostream& operator<< (std::ostream& out, const TDerived& d) { // función amiga return out << d._a << '/' << d._s ; // necesita acceso a parte privada } // Redefinición operador suma entre dos objetos de clase TDerived TDerived operator+ (const TDerived& rhs) { return TDerived (_a + rhs._a, _s + rhs._s); } private: // Parte privada -------------------------------------------- bool checkMe () { return (_a > 0); } // método de instancia privado int _a; // datos de instancia std::string _s; // datos de instancia static int _n; // datos de clase } TDerived d1(1, "example"), d2(2); d1 = d1 + d2;
2.5. Iso C++
C++
no es un lenguaje creado por una compañía particular que de alguna manera controla como evoluciona.- Su desarrollo está gestionado por un comité dentro del estándar ISO.
- A este estándar se han adherido diversos fabricantes de compiladores de C++ entre otros.
- Hay varias versiones publicadas del mismo, nos referimos a ellas por
el año de publicación:
C++98
,C++11
,C++14
,C++17
yC++20
, además está en desarrolloC++23
.
- El comité se ha propuesto publicar una nueva versión cada tres años del estándar del lenguaje.
- Debemos comprobar la documentación del compilador usado para saber qué versión o versiones implementa y en este último caso elegir con cual trabajar.
- Algunos compiladores implementan por defecto una versión y ofrecen
una 'preview' de otra versión posterior mediante el uso de una
opción, p.e., en el caso de '
g++
' versiones recientes implementan ya C++17 y lo usan por defecto pero si no lo hacen podemos forzarlo mediante el uso de la opción de compilación
"--std=c++17
", aC++20
: "--std=c++20
", o incluso al futuroC++23
: "--std=c++23
" o también "--std=c++2b
".
2.6. Enlaces interesantes sobre C++
- Estándar ISO
- Cpp Reference
- The C++ Annotations
- Adaptación de
g++
a los distintos estándares.
3. Gestión y uso de la memoria
3.1. Pila – Stack – (I)
- Es la memoria en la que se guardan variables locales y parámetros de funciones.
Crea un ámbito automático. Es útil pero requiere tener cuidado:
int* suma_elementos (int n[5]) { static bool b = true; int s = 0; for (int i = 0; i < 5; i++) s += n[i]; b = false; return &s; }
Por defecto los parámetros se pasan por valor:
int a = 0; | int a = 0; void inc (int p) { p++; } | void inc (int& p) { p++; } inc (a); | inc (a); // BOOM! | // OK ahora! assert (a == 1); | assert (a == 1);
3.2. Pila – Stack – (II)
Al igual que en
C
podemos crear ámbitos anidados:{ // Ambito I int a = 2; { // Ambito II int b = 4 int a = b; // No es un error } assert ( a == 2 ); // Ok }
C++
permite distinguir una variable global de una local que se llame igual con el operador de resolución de ámbito ( :: ):int a = 7; int f () { int a = 3; return a + ::a; // 10 = 3 + 7 }
3.3. Pila – Stack – (III)
- La llave de apertura '
{
' marca el inicio de un ámbito y la de cierre '}
' el final. - Cualquier variable local a un ámbito, al terminar el mismo, se destruye.
- …pero esto es algo que ya conoceis de Programación-I.
C++
se comporta igual queC
en este aspecto.
3.4. Pila – Stack – (IV)
Hay que llevar especial cuidado con los punteros:
int main () { char* c = new char[20]; return 0; }
- Probado con valgrind:
==7177== Memcheck, a memory error detector ==7177== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. ==7177== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info ==7177== Command: ./a.out ==7177==
- Continúa la salida de valgrind:
==7177== HEAP SUMMARY: ==7177== in use at exit: 72,724 bytes in 2 blocks ==7177== total heap usage: 2 allocs, 0 frees, 72,724 bytes allocated ==7177== ==7177== LEAK SUMMARY: ==7177== definitely lost: 20 bytes in 1 blocks ==7177== indirectly lost: 0 bytes in 0 blocks ==7177== possibly lost: 0 bytes in 0 blocks ==7177== still reachable: 72,704 bytes in 1 blocks ==7177== suppressed: 0 bytes in 0 blocks ==7177== Rerun with --leak-check=full to see details of leaked memory ==7177== ==7177== For counts of detected and suppressed errors, rerun with: -v ==7177== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
3.5. Almacenamiento global.
- Sigue las mismas reglas que en
C
. - Una variable declarada fuera de cualquier función se considera que está en el almacenamiento global.
- La biblioteca estándar de C++ usa el espacio de nombres std.
- El ámbito de vida de estas variables es el del programa.
- En el modelo multi-hilo de C++ las variables globales se comparten por todos los hilos.
3.6. Almacenamiento dinámico (Heap ).
- Gestionado por el lenguaje con nuevos operadores:
new
,new[]
,delete
,delete[]
.
Se pueden usar tanto con tipos básicos como con tipos creados por nosotros:
int* pe = new int(10); // Reserva memoria y la inicializa a 10. delete pe; ... class TArbol {...}; TArbol* a1 = new TArbol; TArbol* a2 = new TArbol (a1); delete a1; delete a2; ... TArbol* va = new TArbol[10]; delete[] va;
- Se pueden sobrecargar a nivel global y por clases. En este vídeo del
canal de Dave Plummer puedes obtener más información al
respecto. También te recomiendo que veas su vídeo donde explica los
problemas con la gestión de memoria que pueden ocurrir con las
funciones de
C
para el tratamiento de cadenas.
3.7. ¿Sabías que…?
El operador
new
se puede simular enC
con ayuda del preprocesador:#define NEW(tipo,cantidad) ((tipo*) malloc((cantidad) * (size_t) sizeof(tipo))) /* 1: array de 20 caracteres */ char* c = NEW(char, 20); // Equivale a: // char* c = (char*) malloc (20 * sizeof(char)) /* 2: Matriz de 20*10 enteros */ int** m; m = NEW(int*, 20); for (int r = 0; r < 20; r++) { m[r] = NEW(int, 10); for (int c = 0; c < 10; c++) m[r][c] = 2*c; }
3.8. ¿Y sabías que también podemos…?
Declarar punteros a funciones, fíjate en este ejemplo:
#include <iostream> using namespace std; void hola(void) { cout << "Hola\n"; } void adios(void) { cout << "Adios\n"; } using fpvv_t = void(*)(void); int main() { fpvv_t f; f = hola; f(); f = adios; f(); return 0; }
4. Introducción a los TADs
4.1. Definición
- Un TAD Es un modelo matemático…
- …de los objetos constituyentes de un tipo de datos, junto con…
- …las funciones que operan sobre estos objetos.
- IMPORTANTE: estas funciones deben formar parte de la especificación del TAD.
- Un ejemplo: el TAD
Conjunto
puede ser definido como la colección de datos que son accedidos por operaciones como launion
,interseccion
ydiferencia
.
4.2. Características de los TADs
- Un TAD no es un Tipo de Datos. Este último es una implementación del modelo matemático especificado por un TAD.
- Un TAD no es una Estructura de Datos. Esta última no es más que una colección de variables en un programa que están conectadas de una manera específica.
- En el diseño y especificación de un TAD nunca se habla de su representación interna. Esto permite usar eficientemente los principos de ocultación de información y de reusabilidad.
- Conseguir una especificación completa y rigurosa de un TAD implica obtener un conjunto de axiomas que lo describen completa e inequivocamente. Esto pude llegar a ser difícil con TADs complejos.
4.3. TADs estudiados
- Listas simple y doblemente enlazadas.
- Pilas
- Colas
- Árboles
- Grafos
5. Aclaraciones
- En ningún caso estas transparencias son la bibliografía de la asignatura, por lo tanto debes estudiar, aclarar y ampliar los conceptos que en ellas encuentres empleando los enlaces web y bibliografía recomendada que puedes consultar en la página web de la ficha de la asignatura y en la web propia de la asignatura.