Tipos Abstractos de Datos.
Created: 2025-01-28 mar 23:20
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 de includes
gratuitos!
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.cfront
era un traductor de C++
a C
.C
.C
(pero no todo programa en C
es
un programa correcto en C++
).C++
es
recomendable que leas estos dos artículos.public
, private
y protected
).and
, or
, not
, xor
, etc…,
además de los que ya conoces de C (&&
, ||
, !
, ^
…).nullptr
typedef
de struct o class.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;
C++
no es un lenguaje creado por una compañía particular que de
alguna manera controla como evoluciona.C++98
, C++11
, C++14
, C++17
, C++20
y C++23
. Además
está en desarrollo C++26
.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
", a C++20
: "--std=c++20
", o a C++23
:
"--std=c++23
".g++
a los distintos estándares.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);
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
}
{
' marca el inicio de un ámbito y la de
cierre '}
' el final.C++
se comporta igual que C
en este aspecto.Hay que llevar especial cuidado con los punteros:
int main () {
char* c = new char[20];
return 0;
}
==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==
==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)
C
.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;
C
para el tratamiento de cadenas.
El operador new
se puede simular en C
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;
}
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;
}
Conjunto
puede ser definido como la
colección de datos que son accedidos por operaciones como la
union
, interseccion
y diferencia
.