C++

**C++** ye un llinguaxe de programación diseñáu a mediaos de los años 1980 por Bjarne Stroustrup. La intención de la so creación foi l'estender al llinguaxe de programación C mecanismos que dexen la manipulación d'oxetos. Nesi sentíu, dende'l puntu de vista de los llinguaxes empobinaos a oxetos, el C++ ye un llinguaxe híbridu.

Darréu añadiéronse facilidaes de programación xenérica, que se sumaron a los paradigmes de programación estructurada y programación empobinada a oxetos. Por esto suel dicir que'l C++ ye un llinguaxe de programación multiparadigma.

Anguaño esiste un estándar, denomináu ISO C++, al que se xuntaron la mayoría de los fabricantes de compiladores más modernos. Esisten tamién dellos intérpretes, tales como ROOT.

Una particularidá del C++ ye la posibilidá de redefinir los operadores, y de poder crear nuevos tipos que se porten como tipos fundamentales.

El nome "C++" foi propuestu por Rick Mascitti nel añu 1983, cuando'l llinguaxe foi utilizáu per primer vegada fuera d'un llaboratoriu científicu. Antes usárase'l nome "C con clases". En C++, la espresión "C++" significa "medría de C" y refierse a que C++ ye una estensión de C.

## Exemplos
De siguío cítase un programa d'exemplu Hola mundu escritu en C++:


```cpp
/* Esta cabecera dexa usar los oxetos que encapsulan los descriptores stdout
y stdin: cout(<<) y cin(>>)*/
#include <iostream>

using namespace std;

int main()
{
 cout << "Hola mundu" << endl;
 return 0;
}
```


Al usar la direutiva `#include` dízse-y al compilador que busque ya interprete tolos elementos definíos nel archivu qu'acompaña la direutiva (nesti casu, `iostream`). Pa evitar sobrescribir los elementos yá definíos al pone-yos igual nome, creáronse los espacios de nomes o `namespace` del singular n'inglés. Nesti casu hai un espaciu de nomes llamáu `std`, que ye onde s'inclúin les definiciones de toles funciones y clases que conformen la biblioteca estándar de C++. Al incluyir la sentencia `using namespace std` tamos diciéndo-y al compilador que vamos usar l'espaciu de nomes `std` polo que nun vamos tener qu'incluyilo cuando usemos elementos d'esti espaciu de nomes, como pueden ser los oxetos `cout` y `cin`, que representen el fluxu de salida estándar (típicamente la pantalla o una ventana de testu) y el fluxu d'entrada estándar (típicamente'l tecláu).

La definición de funciones ye igual qu'en C, sacante pola carauterística de que si `main` nun va recoyer argumentos, nun tenemos por qué pone-y los, a diferencia de C, onde había que ponelos explícitamente, anque nun se fueren usar. Queda solo comentar que'l símbolu `<<` conozse como operador d'insertamientu, y *grosso modo* ta unviando a `cout` lo que queremos amosar por pantalla por que lo pinte, nesti casu la cadena `"Hola mundu"`. El mesmu operador `<<` puede usase delles vegaes na mesma sentencia, de forma que gracies a esta carauterística vamos poder concatenar l'oxetu `endl` a la fin, que'l so resultáu va ser imprimir una torna de llinia.

## Tipos de datos
C++ tien los siguientes tipos fundamentales:
* Calteres: `char` (tamién ye un enteru), `wchar_t`
* Enteros: `short`, `int`, `long`, `long long`
* Númberos en coma flotante: `float`, `double`, `long double`
* Booleanos: `bool`
* Vacíu: `void`

El modificador `unsigned` puede aplicase a enteros pa llograr númberos ensin signu (por omisión los enteros contienen signu), colo que se consigue un rangu mayor de númberos naturales.

### Tamaños asociaos

Según la máquina y el compilador que s'utilice los tipos primitivos pueden ocupar un determináu tamañu en memoria. La siguiente llista ilustra'l númberu de bits qu'ocupen los distintos tipos primitivos na arquiteutura x86.

Otres arquitectures pueden riquir distintos tamaños de tipos de datos primitivos. C++ nun diz nada alrodiu de cuál ye'l númberu de bits nun byte, nin del tamañu d'estos tipos; más bien, ufierta solamente les siguientes "garantíes de tipos":

* D'alcuerdu al estándar C99, un tipu `char` tien d'ocupar esautamente un *byte* compuestu d'un mínimu de 8 *bits* independientemente de l'arquiteutura de la máquina.
* El tamañu reconocíu de `char` ye de 1. Esto ye, `sizeof(char)` siempres devuelve 1.
* Un tipu `short` tien *siquier el mesmu* tamañu qu'un tipu `char`.
* Un tipu `long` tien *siquier el doble* tamañu en bytes qu'un tipu `short`.
* Un tipu `int` tien un tamañu ente'l de `short` y el de `long`, dambos inclusive, preferentemente el tamañu d'un apuntador de memoria de la máquina. El so valor máximu ye 2147488281, usando 32 bits.
* Un tipu `unsigned` tien el mesmu tamañu que la so versión `signed`.

### Wchar_t
Pa la versión del estándar que se publicar en 1998, decidió añader el tipu de datu `wchar_t`, que dexa l'usu de calteres Unicode, a diferencia del tradicional `char`, que contempla a cencielles al códigu de calteres ASCII estendíu. De la mesma, definióse pa la mayoría de les funciones y clases, tanto de C como de C++, una versión pa trabayar con `wchar_t`, onde usualmente se prefija el calter *w* al nome de la función (n'ocasiones el calter ye un infixu). Por casu:

* `strcpy - wstrcpy`
* `std::string - std::wstring`
* `std::cout - std::wcout`

Cabo resaltar qu'en C se define `wchar_t` como:


```cpp
typedef unsigned short wchar_t;
```


Ente qu'en C++ ye en sí mesmu un tipu de datu.

### La pallabra reservada "void"
La pallabra reservada `void` define en C++ el conceutu de non esistencia o non atribución d'un tipu nuna variable o declaración. Esto ye, una función declarada como `void` nun va devolver nengún valor. Esta pallabra reservada tamién puede usase pa indicar qu'una función nun recibe parámetros, como na siguiente declaración:


```cpp
int funcion (void);
```

Anque l'enclín actual ye la de nun asitiar la pallabra "void".

Amás utilízase pa determinar qu'una función nun retorna un valor, como en:

```cpp
void funcion (int parametru);
```


Hai de solliñar que **<code>void</code> nun ye un tipu**. Una función como la declarada enantes nun puede retornar un valor per mediu de return: la pallabra clave va sola. Nun ye posible una declaración del tipu:

```cpp
void t; //Ta mal
```


Nesti sentíu, `void` portar de forma llixeramente distinta a como lo fai en C, especialmente tocantes al so significáu en declaraciones y prototipos de funciones.

Sicasí, la forma especial void * indica que'l tipu de datos ye un punteru. Por casu:


```cpp
void *memoria;
```


Indica que memoria ye un punteru a *dalguna parte*, onde se guarda información de *dalgún tipu*. El programador ye responsable de definir estos "dalgún", esaniciando toa ambigüedá. Una ventaya de la declaración "*void **" ye que puede representar al empar dellos tipos de datos, dependiendo de la operación de ''cast'' escoyida. La memoria qu'apuntemos ayundes, nel exemplu anterior, bien podría almacenar un enteru, un flotante, una cadena de testu o un programa, o combinaciones d'estos. Ye responsabilidá del programador recordar qué tipu de datos hai y garantizar l'accesu fayadizu.

### La pallabra "NULL"
Amás de los valores que pueden tomar los tipos enantes mentaos, esiste un valor llamáu NULL, seya los casu numbéricu pa los enteros, calter pal tipu char, cadena de testu pal tipu string, etc. El valor NULL, espresa, polo regular, la representación d'una Macro, asignada al valor "0".

Tenemos entós que:


```cpp
void* piqueru = NULL;
int enteru = NULL;
bool boleana = NULL;
char caracter = NULL;
```


El valor de les variables anteriores daríanos 0. A diferencia de la variable "caracter", que nos daría l'equivalente a NULL, '\0', pa calteres.

## Principios
Tou programa en C++ tien de tener la función principal `main()` (sacantes que se especifique en tiempu de compilación otru puntu d'entrada, qu'en realidá ye la función que tien el `main()`)

```cpp
int main()
{}
```


La función principal del códigu fonte main tien de tener unu de los siguientes prototipos:
int main()
int main(int argc, char** argv)

Anque nun ye estándar delles implementaciones dexen
int main(int argc, char** argv, char** env)

La primera ye la forma por omisión d'un programa que nun recibe parámetros nin argumentos. La segunda forma tien dos parámetros: *argc*, un númberu que describe'l númberu d'argumentos del programa (incluyendo'l nome del programa mesmu), y *argv*, un punteru a un array de punteros, de *argc* elementos, onde l'elementu argv[i] representa'l *i*-ésimo argumentu apurríu al programa. Nel tercer casu añader la posibilidá de poder aportar a les variables de redolada d'execución de la mesma forma que s'apuerta a los argumentos del programa, pero reflexaos sobre la variable *env*.

El tipu de torna de main ye un valor enteru **int**. Al rematar la función `main`, tien d'incluyise'l valor de torna (por casu, return 0;, anque l'estándar preve solamente dos posibles valores de torna: EXIT_SUCCESS y EXIT_FAILURE, definíes nel archivu cstdlib), o salir per mediu de la función exit. Alternativamente puede dexase en blancu, y nesi casu el compilador ye responsable d'amestar la salida fayadiza.

## El conceutu de clase

Los oxetos en C++ son abstraídos por aciu una clase. Según el paradigma de la programación empobinada a oxetos un oxetu consta de:

# Identidá, que lo estrema d'otros oxetos (Nome que va llevar la clase a la que pertenez dichu oxetu).
# Métodos o funciones miembro #
Atributo o variables miembru

Un exemplu de clase que podemos tomar ye la clase perru. Cada perru comparte unes carauterístiques (atributos). El so númberu de pates, el color de la so pelame o'l so tamañu son dalgunos de los sos atributos. Les funciones que la faigan llatir, camudar el so comportamientu... eses son les funciones de la clase.

Este ye otru exemplu d'una clase:


```cpp
class Puntu {

//per omisión, los miembros son 'private' por que solo puedan modificar dende la mesma clase.
private:
 // Variable miembru privada int
 id;
protected:
 // Variables miembru protexíes
 int x;
 int y;
public:
 // Constructor
 Puntu();
 // Destructor
 ~Puntu();
 // Funciones miembru o métodos
 int ObtenerX();
 int ObtenerY();
};
```


### Constructores

Son unos métodos especiales que s'executen automáticamente al crear un oxetu de la clase. Na so declaración nun s'especifica'l tipu de datu que devuelven, y tienen el mesmu nome que la clase a la que pertenecen.
Al igual qu'otros métodos, puede haber dellos constructores sobrecargados, anque nun pueden esistir constructores virtuales.

Como carauterística especial a la d'implementar un constructor, xusto dempués de la declaración de los parámetros, atópase lo que se llama "llista de inicializadores". El so oxetivu ye llamar a los constructores de los atributos que conformen l'oxetu a construyir.

Hai de solliñar que nun ye necesariu declarar un constructor al igual qu'un destructor, pos el compilador puede facer, anque nun ye la meyor forma de programar.

Tomando l'exemplu de la Clase Puntu, si deseyamos que cada vez que se cree un oxetu d'esta clase les coordenaes del puntu sían igual a cero podemos amestar un constructor como s'amuesa de siguío:.


```cpp
class Puntu {

 public:

 float x; // Coordenaes del puntu float
 y;

 // Constructor
 Puntu() : x(0), y(0){ // Inicializamos les variables "x" y "y"
 }
};

// Main pa demostrar el funcionamientu de la clase

# include <iostream> // Esto déxanos utilizar "cout"

using namespace std;

int main () {
 Puntu MiPunto; // creamos un elementu de la clase Puntu llamáu MiPunto

 cout << "Coordenada X: " << MiPunto.x << endl; // amosemos el valor acumuláu na variable x
 cout << "Coordenada Y: " << MiPunto.y << endl; // amosemos el valor acumuláu na variable y getchar();
 // indicámos-y al programa qu'espere al buffer d'entrada (detenese)
 return 0;
}
```


Si compilamos y executamos l'anterior programa, llogramos una salida que tien de ser similar a la siguiente:

Coordenada X: 0
Coordenada Y: 0

Esisten dellos tipos de constructores en C++:

# **Constructor predeterminado**. Ye'l constructor que nun recibe nengún parámetru na función. Si nun se definiera nengún constructor, el sistema apurriría unu predeterminado. Ye necesariu pa la construcción d'estructures y contenedores de la STL.
# **Constructor de copia**. Ye un constructor que recibe un oxetu de la mesma clase, y realiza una copia de los atributos del mesmu. Al igual que'l predeterminado, si nun se define, el sistema apurre unu.
# **Constructor de conversión**. Esti constructor, recibe como únicu parámetru, un oxetu o variable d'otru tipu distintu al so propiu. Esto ye, convierte un oxetu d'un tipu determináu a otru oxetu del tipu que tamos xenerando.

**Constructores + Memoria heap**
Un oxetu creáu de la forma que se vio hasta agora, ye un oxetu que vive dientro del scope(les llaves { }) nel que foi creáu. Por que un oxetu pueda siguir viviendo cuando se saque del scope nel que se creó, tien de crear en memoria heap. Pa esto, utilízase l'operador new, que asigna memoria p'almacenar al oxetu creáu, y amás llama al so constructor(polo que se-y pueden unviar parámetros). L'operador new utilizar de la siguiente manera:


```cpp
int main() {
 Puntu *unPunto = new Puntu(); //esto llapada al constructor que se describe más arriba
 delete unPunto; //nun hai qu'escaecese de lliberar la memoria ocupada pol oxetu(ver la seición destructores, más embaxo)
 return 0;
}
```


Amás, col operador new[] pueden crease arrays (coleiciones o llistes ordenaes) de tamañu dinámicu:


```cpp
Puntu *asignar(int cuantos) {
 return new Puntu[cuantos]; //asigna un array de 'cuantos' puntos(llámase'l constructor que s'amuesa más arriba), y retornar.
}
```


### Destructores

Los destructores son funciones miembru especiales llamaes automáticamente na execución del programa, y por tanto **nun tienen por qué ser llamaes explícitamente pol programador**. Los sos principales cometíos son:
* Lliberar los recursos computacionales que l'oxetu de dicha clase adquiriera en tiempu d'execución al expirar este.
* Quitar los venceyos que pudieren tener otros recursos o oxetos con este.

Los destructores son invocaos automáticamente al algamar el fluxu del programa'l fin del ámbitu nel que ta declaráu l'oxetu. L'únicu casu nel que se debe **invocar explícitamente al destructor d'un oxetu**, ye cuando esti foi creáu por aciu l'operador new, esto ye, qu'esti vive en memoria heap, y non na pila d'execución del programa. La invocación del destructor d'un oxetu que vive en heap realízase al traviés del operador delete o delete[] pa arrays. Exemplu:


```cpp
int main() {
 int *unEntero = new int(12); //asignamos un enteru en memoria heap col valor 12
 int *arrayDeEnteros = new int[25]; //asignamos memoria pa 25 enteros(nun tán inicializados)
 delete unEntero; //lliberamos la memoria qu'ocupaba unEntero
 delete[] arrayDeEnteros; //lliberamos la memoria ocupada por arrayDeEnteros
 return 0;
}
```


Si nun s'utilizara l'operador delete y delete[] nesi casu, la memoria ocupada por unEntero y arrayDeEnteros respeutivamente, quedaría ocupada ensin sentíu. Cuando una porción de memoria queda ocupada por una variable que yá non s'utiliza, y nun hai forma d'aportar a ella, denominar un 'memory leak'. N'aplicaciones grandes, si asoceden munchos memory leaks, el programa puede terminar ocupando abondo más memoria RAM de la que debería, lo que nun ye pa nada conveniente. Ye por esto, que'l manexu de memoria heap tien d'usase conscientemente.

Esisten dos tipos de destructores pueden ser públicos o privaos, según si declárense:
* Si ye públicu llamar dende cualesquier parte del programa pa destruyir l'oxetu.
* Si ye quitáu nun se dexa la destrucción del oxetu pol usuariu.

L'usu de destructores ye clave nel conceutu d'Adquirir Recursos ye Inicializar.

### Funciones miembru
Función miembro ye aquella que ta declarada n'ámbitu de clase. Son similares a les funciones habituales, cola salvedá de que'l compilador realizara'l procesu de **Decoración de nome** (*Name Mangling* n'inglés): Va Camudar el nome de la función añadiendo un identificador de la clase na que ta declarada, pudiendo incluyir calteres especiales o identificadores numbéricos. Esti procesu ye invisible al programador. Amás, funcionar miembru reciben implícitamente un parámetru adicional: El punteru this, que referencia al oxetu qu'executa la función.

Funcionar miembru invóquense aportando primero al oxetu al cual refieren, cola sintaxis: myobject.mymemberfunction(), esto ye un claru exemplu d'una función miembru.

Casu especial ye'l de funcionar miembru estátiques. A pesar de que son declaraes dientro de la clase, col usu de la pallabra clave static nun van recibir el punteru this. Gracies a esto nun ye necesariu crear nenguna instancia de la clase pa llamar a esta función, sicasí, solo podrá aportase a los miembros estáticos de la clase yá que estos nun tán acomuñaos al oxetu sinón al tipu. La sintaxis pa llamar a esta función estática ye mytype::mystaticmember().

### Plantíes
Les plantíes son el mecanismu de C++ pa enllantar el paradigma de la programación xenérica. Dexen qu'una clase o función trabaye con tipos de datos astractos, especificándose más palantre cualos son los que quieren usase. Por casu, ye posible construyir un vector xenéricu que pueda contener cualquier tipu d'estructura de datos. D'esta forma pueden declarase oxetos de la clase d'esti vector que contengan enteros, flotantes, polígonos, figures, fiches de personal, etc.

La declaración d'una plantía realízase anteponiendo la declaración template  a la declaración de la estructura (clase, estructura o función) deseyáu.

Por casu:


```cpp
template <typename T>
T max(const T &x, const T &y) {
 return (x > y) ? x : y; //si x > y, retorna x, sinón retorna y }
```


La función max() ye un exemplu de programación xenérica, y daos dos parámetros d'un tipu T (que puede ser int, long, float, double, etc.) va devolver el mayor d'ellos (usando l'operador >). Al executar la función con parámetros d'un ciertu tipu, el compilador va intentar "calzar" la plantía a esi tipu de datos, o bien va xenerar un mensaxe d'error si fracasa nesi procesu.

#### Especialización
El siguiente exemplu:


```cpp
template <typename A> int myfunction(A a);
```


crea una plantía so la cual pueden ser definíes nel códigu de cabecera cualesquier funciones especializaes pa un tipu de datos como int myfunction(int), int myfunction(std::string), int myfunction(bool), etcétera:


```cpp
int myfunction (int a) {
 return a + 5;
};

int myfunction (std::string a) {
 return -a.size();
};

int myfunction (bool a) {
 return (a & rand()); //Si a ye verdaderu, devuelve un númberu aleatoriu; en casu contrariu devuelve 0
};
```


Caúna d'estes funciones tien la so propia definición (cuerpu). Cada cuerpu distintu, non equivalente ("non convertible") correspuende a una **especialización**. Si una d'estes funciones nun fuera definida, el compilador va tratar d'aplicar les conversiones de tipos de datos que-y fueren dexaes pa "calzar" una de les plantíes, o va xenerar un mensaxe d'error si fracasa nesi procesu.

Toles definiciones habilitaes d'una plantía tienen de tar disponibles al momentu de la compilación, polo cual nun ye posible anguaño "compilar" una plantía como archivu d'oxetu, sinón a cencielles compilar especializaciones de la plantía. Poro, les plantíes distribúyense xunto col códigu fonte de l'aplicación. N'otres pallabres, nun ye posible compilar la plantía std::vector a códigu oxetu, pero sí ye posible, por casu, compilar un tipu de datos std::vector.

### ‎Clases astractes
En C++ ye posible definir clases astractes. Una clase astracta, o clase base astracta (ABC), ye una que ta diseñada solo como clase *padre* de les cualos débense derivar clases fíes. Una clase astracta usar pa representar aquelles entidaes o métodos que dempués s'implementarán nes clases derivaes, pero la clase astracta en sí nun contién nenguna implementación -- solamente representa los métodos que se deben implementar. Por ello, nun ye posible instanciar una clase astracta, pero sí una clase concreta qu'implemente los métodos definíos nella.

Les clases astractes son útiles pa definir interfaces, esto ye, un conxuntu de métodos que definen el comportamientu d'un módulu determináu. Estes definiciones pueden utilizase ensin tener en cuenta la implementación que se va faer d'ellos.

En C++ los métodos de les clases astractes defínense como funciones virtuales pures.


```cpp
class Astracta {

 public:
 virtual int metodo() = 0;
}

class ConcretaA : public Astracta {

 public:
 int metodo()
 {
 //fai daqué return
 foo () + 2;
 }
};

class ConcretaB : public Astracta {

 public:
 int metodo()
 {
 //otra implementación
 return baz () - 5;
 }
};
```

Nel exemplu, la clase ConcretaA ye una implementación de la clase Astracta, y la clase ConcretaB ye otra implementación.
Tien De notase que'l = 0 ye la notación qu'emplega C++ pa definir funciones virtuales pures.

### Espacios de nomes
Una adición a les carauterístiques de C son los **espacios de nome** (*namespace* n'inglés), que pueden describise como árees virtuales so les cualos ciertos nomes de variable o tipos tienen validez. Esto dexa evitar los escurrimientos de conflictos ente nomes de funciones, variables o clases.

L'exemplu más conocíu en C++ ye l'espaciu de nomes std::, que almacena toles definiciones nueves en C++ que difieren de C (delles estructures y funciones), según les funcionalidades propies de C++ (*streams*) y los componentes de la biblioteca STL.

Por casu:


```cpp
# include <iostream>
// Les funciones nesta cabecera esisten dientro del espaciu de nomes std::

namespace mio_paquete{
 int mio_valor;
};

int main()
{
 int mio_valor = 3;
 mio_paquete::mio_valor = 4;

 std::cout << mio_valor << '\n'; // imprime '3'
 std::cout << mio_paquete::mio_valor << '\n'; // imprime '4'

 return 0;
}
```


Como puede trate, les invocaciones direutes a *mio_valor* van dar accesu solamente a la variable descrita llocalmente; p'aportar a la variable del espaciu de nomes *mio_paquete* ye necesariu aportar específicamente l'espaciu de nomes. Un atayu encamentáu pa programes senciellos ye la direutiva using namespace, que dexa aportar a los nomes de variables del paquete deseyáu en forma direuta, siempres y cuando nun se produza dalguna ambigüedá o conflictu de nomes.

### Heriedu
Esisten dellos tipos d'heriedu ente clases nel llinguaxe de programación C++. Estos son:

#### Heriedu simple
L'heriedu en C++ ye un mecanismu d'astracción creáu pa poder facilitar y ameyorar el diseñu de les clases d'un programa. Con ella puédense crear nueves clases a partir de clases yá feches, siempres y cuando tengan un tipu de rellación especial.

Nel heriedu, les clases derivaes "herieden" los datos y funcionar miembru de les clases base, pudiendo les clases derivaes redefinir estos comportamientos (polimorfismu) y añader comportamientos nuevos propios de les clases derivaes.
Pa nun romper el principiu de encapsulamiento (despintar datos que'l so conocencia nun ye necesariu pal usu de les clases), apúrrese una nueva manera de visibilidá de los datos/funciones: "protected". Cualquier cosa que tenga visibilidá protected va portase como pública na clase Base y nes que componen la xerarquía d'heriedu, y como privada nes clases que NUN sían de la xerarquía del heriedu.

Antes d'utilizar l'heriedu, tenémonos que faer una entruga, y si tien sentíu, podemos intentar usar esta xerarquía: Si la frase  YE-UN  tien sentíu, entós tamos ante un posible casu d'heriedu onde clase A va ser la clase base y clase B la derivada.

Exemplu: clases Barco, Acorazáu, Cargueru, etc. Un Acorazáu YE-UN Barcu, un Cargueru YE-UN Barcu, un Tresatlánticu YE-UN Barcu, etc.

Nesti exemplu tendríamos les coses xenerales d'un Barcu (en C++)

```cpp
class Barcu {
 protected:
 char* nome;
 float pesu;
 public:
 //Constructores y demás funciones básiques de barcu };
```

y agora les carauterístiques de les clases derivaes, podríen (al empar qu'herieden les de barcu) añader coses propies del subtipo de barcu que vamos crear, por casu:


```cpp
class Cargueru: public Barcu { // Esta ye la manera d'especificar qu'herieda de Barcu private:
 
 float carga;
 //El restu de coses
};

class Acorazáu: public Barcu {
 private:
 int numeroArmas;
 int Soldaos;
 // El restu de coses
};
```


A lo último, hai que mentar qu'esisten 3 clases d'heriedu que s'estremen na manera de remanar la visibilidá de los componentes de la clase resultante:

* Heriedu públicu (class Derivada: public Base ): Con esti tipu d'heriedu respeten los comportamientos orixinales de les visibilidaes de la clase Base na clase Derivada.
* Heriedu priváu (clase Derivada: private Base): Con esti tipu d'heriedu tou componente de la clase Base, va ser quitáu na clase Derivada (les propiedaes heredaes van ser quitaes anque estes sían públiques na clase Base)
* Heriedu protexíu (clase Derivada: protected Base): Con esti tipu d'heriedu, tou componente públicu y protexíu de la clase Base, va ser protexíu na clase Derivada, y los componentes privaos, siguen siendo privaos.

#### Heriedu múltiple
La heriedu múltiple ye'l mecanismu que dexa al programador faer clases derivaes a partir, non d'una sola clase base, sinón de delles. Pa entender esto meyor, pongamos un exemplu:
Cuando ves a quien te atiende nuna tienda, como persona que ye, vas poder suponer que puede falar, comer, andar, pero, per otru llau, como emplegáu que ye, tamién vas poder suponer que tien un xefe, que puede cobrate dineru pola compra, que puede devolvete'l cambéu, etc. Si esto treslladar a la programación sería heriedu múltiple (clase emplegáu_tienda):


```cpp
class Persona {
 ...
 Falar();
 Caminar();
 ...
};

class Emplegáu {
 Persona xefe;
 int sueldu;
 Cobrar();
 ...
};

class EmpleadoTienda: public Persona, Emplegáu {
 ...
 AlmacenarStock();
 ComprobarExistencias();
 ...
};
```


Por tanto, ye posible utilizar más d'una clase por qu'otra heriede les sos carauterístiques.

### Sobrecarga d'operadores
La sobrecarga d'operadores ye una forma de faer polimorfismu. Ye posible definir el comportamientu d'un operador del llinguaxe por que trabaye con tipos de datos definíos pol usuariu. Non tolos operadores de C++ son facederos de sobrecargar, y, ente aquellos que pueden ser sobrecargados, tienen de cumplise condiciones especiales. En particular, los operadores sizeof y :: nun son sobrecargables.

Nun ye posible en C++ crear un operador nuevu.

Los comportamientos de los operadores sobrecargados implementar de la mesma manera qu'una función, sacantes esta va tener un nome especial: `''Tipu de datu de devolución'' '''operator<token del operador>'''(''parámetros'')`

Los siguientes operadores pueden ser sobrecargados:

* Operadores Unarios
** Operador * (de indirección)
** Operador -> (de indirección)
** Operador & (de direición)
** Operador +
** Operador -
** Operador ++
** Operador --
* Operadores Binarios
** Operador ==
** Operador +
** Operador -
** Operador
* ** Operador /
** Operador %
** Operador >
** Operador &
** Operador ^
** Operador |
** Operador []
** Operador ()
* Operadores de Asignación
** Operador =
** Operador +=
** Operador -=
** Operador *=
** Operador /=
** Operador %=
** Operador >=
** Operador &=
** Operador ^=
** Operador |=

Puesto que esti operadores son definíos pa un tipu de datos definíu pol usuariu, este ye llibre d'asigna-yos cualesquier semántica que deseye. Sicasí, considérase de primera importancia que les semántiques sían tan paecíes al comportamientu natural de los operadores como por que el usu de los operadores sobrecargados seya intuitivu. Por casu, l'usu del operador unario - tuviera de camudar el "signu" d'un "valor".

Los operadores sobrecargados nun dexen de ser funciones, polo que pueden devolver un valor, si esti valor ye del tipu de datos col que trabaya l'operador, dexa l'encadenamientu de sentencies. Por casu, si tenemos 3 variables A, B y C d'un tipu T y sobrecargamos l'operador = por que trabaye col tipu de datos T, hai dos opciones: si l'operador nun devuelve nada una sentencia como "A=B=C;" (ensin les comines) daría error, pero si devuélvese un tipu de datos T al implementar l'operador, dexaría concatenar cuantos elementos quixérense, dexando daqué como "A=B=C=D=...;"

## Standard Template Library (STL)

Los llinguaxes de programación suelen tener una serie de biblioteques de funciones integraes pa la manipulación de datos a nivel más básicu. En C++, amás de poder usar les biblioteques de C, puede usase la nativa STL (Standard Template Library), mesma del llinguaxe. Apurre una serie plantíes (templates) que dexen efectuar operaciones sobre l'almacenáu de datos, procesáu d'entrada salida.

## Biblioteca d'entrada y salida
Les clases **basic_ostream** y **basic_stream**, y los oxetos **cout** y **cin**, apurren la entrada y salida estándar de datos (teclado/pantalla). Tamién ta disponible **cerr**, similar a cout, usáu pa la salida estándar d'errores.
Estes clases tienen sobrecargados los operadores >, respeutivamente, al envís de ser útiles nel insertamientu/estracción de datos a dichos fluxos. Son operadores intelixentes, yá que son capaces d'afaese al tipu de datos que reciben, anque vamos tener que definir el comportamientu de dicha entrada/salida pa clases/tipo de datos definíos pol usuariu. Por casu:


```cpp
ostream& operator<<(ostream& fs, const Puntu& puntu)
{
 return fs << puntu.x << "," << puntu.y;
}
```


D'esta forma, p'amosar un puntu, solo habría que realizar la siguiente espresión:

```cpp
//...
Puntu p(4,5);
//...
cout << "Les coordenaes son: " << p << endl;
//...
```


Ye posible formatear la entrada salida, indicando'l númberu de díxitos decimales a amosar, si los testos van pasar a minúscules o mayúscules, si los númberos recibíos tán en formatu octal o hexadecimal, etc.

### Fstreams
Tipu de fluxu pal manexu de ficheros. La definición previa de *ostreams/istreams* ye aplicable a esti apartáu.
Esisten tres clases (ficheros de llectura, d'escritura o de llectura/escritura): **ifstream**,**ofstream** y **fstream**.

Como abrir un ficheru:
(nome_variable_ficheru).open("nome_ficheru.dat/txt", ios::in); p'abrir en modo lectura.
(nombrevariablefichero).open("nome_ficheru.dat/txt", ios::out); p'abrir en modo escritura.

Exemplu:
f.open("datos.txt", ios::in);

Como cerrar el ficheru:
nome_variable_ficheru.close();

Exemplu:
f.close();

Lleer un ficheru:
 1-Si ye ficheru de testu planu:
 
```cpp
#include <fstream>
 #include <string>
 #include <iostream>

 using namespace std;

 int main() {
 ifstream entrada;
 entrada.open("textoPlano.txt");
 string unString;
 while(entrada >> unString)
 cout << "Lei: " << unString << endl;
 return 0;
 }
```


 2-Si ye un ficheru binariu(.dat);
 nome_variable_ficheru.read((char*)&nome_variable, sizeof(tipu_variable));

 Exemplu:

 f.read((char*)&y, sizeof(int));
Escribir un ficheru:
 1-Si ye ficheru de testu(.txt):
 nombrevariable>>.
Exemplos:


```cpp
ostringstream s;
s << nome << "," << edá << "," << estatura << "," << puntu(5,6) << endl;
cout << s.str();
istringstream s(cadena);
s >> nome >> edá >> estatura >> p;
```


### Contenedores
Son clases plantíes especiales utilizaes p'almacenar tipos de datos xenéricos, sían cualos sían. Tolos contenedores son homoxéneos, esto ye, una vegada que se declaren pa contener un tipu de datu determináu, nesi contenedor, solo podrán metese elementos d'esi tipu.
Según la naturaleza del almacenáu, disponemos de dellos tipos:
* Vectores: Definir por 
```
vector<tipu_de_datu> nome_del vector;
```
 Son arrays (o llistes ordenaes) que se redimensionan automáticamente al amestar nuevos elementos, polo que se-y pueden amestar "teóricamente", infinitos elementos. Los vectores déxennos aportar a cualquier elementu que contenga, por aciu l'operador[]. Tien De tenese en cuenta que si s'intenta aportar a una posición qu'entepasa les llendes del vector, esti nun va faer nengún chequeo, polo que se debe ser cuidadosu al utilizar esti operador. P'asegurar un accesu seguru al vector, puede utilizase el métodu at(int), que llanza una esceición de tipu std::out_of_range en casu de qu'esto asoceda.
P'añader elementos a la fin del vector, utilízase'l métodu push_back(const T&). Per otru llau, pa esaniciar un elementu del final del vector, tien d'usase'l métodu pop_back().

```cpp
#include <vector> //llibrería que contién a la clase vector
#include <iostream>
using namespace std;

int main() {
 vector<int> intVector; //crea un vector d'enteros (ensin elementos)
 intVector.push_back(25); //amiesta l'enteru 25 al vector
 cout << "El primer elementu ye: " << intVector.front() <<
 " y el mio vector tien " << intVector.size() << " elementos." << endl; //imprime'l primer elementu, retornáu pol métodu front()

 intVector.push_back(32); //amiesto l'enteru 32 al vector
 cout << "El primer elementu ye: " << intVector[0] << endl; //imprime 25
 intVector.pop_back(); //esanicia l'últimu elementu del vector (i. y. 32)
 cout << "Agora tengo: " << intVector.size() << " elementos." << endl; //va imprimir 1

 return 0;
}
```

* Coles dobles: son paecíes a los vectores, pero tienen meyor eficiencia p'amestar o esaniciar elementos nes "puntes".
```
deque<tipu_de_datu> nome_de_la cola;
```

Amás de los métodos push_back(const T&) y pop_back(), amiéstense los métodos push_front(const T&) y pop_front(), que realicen lo mesmo que los yá esplicaos, pero nel empiezu de la cola.


```cpp
#include <deque> //llibrería de deques

using namespace std;

int main() {
 deque<int> intDeque;
 intDeque.push_front(25);
 intDeque.push_back(12);
 while(intDeque.size())
 intDeque.pop_back(); //borra tolos elementos
 return 0;
}
```

* Llistes: Son eficientes a la d'amestar elementos. La diferencia coles coles dobles, ye que son más eficientes pa esaniciar elementos que nun tean en dalguna de les "puntes"
```
list<tipu_de_datu> nome_de_la llista;
```

* Adaptadores de secuencia.
* Contenedores asociativos: map y multimap, que dexen acomuñar una "clave" con un "valor". map nun dexa valores repitíos, ente que multimap si.

```
map<tipu_de_llave, tipu_de_datu> nome_d'el_map;
multimap<tipu_de_llave, tipu_de_datu> nome_d'el_multimap;
```



```cpp
#include <map> //llibrería que contién a map y multimap
#include <string> //llibrería de strings
#include <iostream> //llibrería d'entrada salida

using namespace std;

int main() {
 map<int, string> intAString;
 intAString[1] = "unu";
 intAString[10] = "diez";
 cout << "En intAString[1]: " << intAString[1] << endl;
 cout << "En intAString[10]: " << intAString[10] << endl;
 return 0;
}
```

* Contenedores asociativos: set y multiset, qu'ufierten solamente la condición de "pertenencia", ensin la necesidá de garantizar un ordenamientu particular de los elementos que contienen.

### Iteradores
Pueden considerase como una xeneralización de la clase de "piqueru". Un iterador ye un tipu de datu que dexa'l percorríu y la busca d'elementos nos contenedores.
Como les estructures de datos (contenedores) son clases xenériques, y los operadores (algoritmos) que tienen d'operar sobre elles son tamién xenéricos (funciones xenériques), Stepanov y los sos collaboradores tuvieron que desenvolver el conceutu de iterador como elementu o nexu de conexón ente dambos. El nuevu conceutu resulta ser una especie de punteros que señalen a los diversos miembros del contenedor (punteros xenéricos que como tales nun esisten nel llinguaxe).

### Algoritmos
Combinando l'usu de templates y un estilu específicu pa denotar tipos y variables, la STL ufierta una serie de funciones que representen operaciones comunes, y que'l so oxetivu ye "parametrizar" les operaciones en qu'estes funciones vense arreyaes de cuenta que la so llectura, comprensión y caltenimientu, sían más fáciles de realizar.

Un exemplu ye la función copy, que a cencielles copia variables dende un llugar a otru. Más puramente, copia los conteníos que les sos allugamientos tán delimitadas por dos iteradores, al espaciu indicáu por un tercer iterador. La sintaxis ye: 
```
copy (empecipio_orixe, fin_orixe, empecipio_destín);
```
 D'esta miente, tolos datos que tán ente entamu_orixe y fin_orixe, escluyendo'l datu allugáu nesti postreru, son copiaos a un llugar descritu o apuntáu por entamu_destino.

Un algoritmu bien importante que vien implementáu na biblioteca STL, ye'l sort. L'algoritmu sort, ordena cualquier tipu de contenedor, siempres y cuando se-y pasen como argumentos, dende onde y hasta onde quier ordenar lo.


```cpp
#include <vector>
#include <deque>
#include <algorithm>

int main() {
 vector<int> intVector;
 intVector.push_back(60);
 intVector.push_back(12);
 intVector.push_back(54); //pa esti momentu, el vector tien 60,12,54
 sort(intVector.begin(), intVector.end()); //llistu, array ordenáu, agora tien 12,54,60
 /*Notar que si en cuenta de un vector, fuera una deque, ordenar de la mesma manera. */
}
```


Ente les funciones más conocíes tán swap (variable1, variable2), qu'a cencielles intercambia los valores de variable1 y variable2; max (variable1, variable2) y el so símil min (variable1, variable2), que retornen el máximu o mínimu ente dos valores; find (entamu, fin, valor) que busca valor nel espaciu de variables ente entamu y fin; etcétera.

Los algoritmos son bien variaos, dalgunos inclusive tienen versiones específiques pa operar con ciertos iteradores o contenedores, y aproven un nivel d'astracción extra que dexa llograr un códigu más "llimpiu", que "describe" lo que se ta faciendo, en cuenta de faelo pasu a pasu explícitamente.

## C++11

El 12 d'agostu de 2011, Herb Sutter, presidente del comité d'estándares de C++, informó l'aprobación unánime del nuevu estándar. La publicación del mesmu realizóse en dalgún momentu del 2011.

Ente les carauterístiques del nuevu estándar pueden destacar:

* Funciones lambda;
* Referencies rvalue;
* La pallabra reservada auto;
* Inicialización uniforme;
* Plantíes con númberu variable d'argumentos.

Amás actualizóse la biblioteca estándar del llinguaxe.

## Actualidá y futuru
La continuidá del C++11 ye C++14, que ye la versión actual, y nel futuru, envalórase qu'a finales de 2017, va ser C++17

## Diferencies de tipos al respective de C
En C++, cualquier tipu de datos que seya *declaráu completu* (*fully qualified*, n'inglés) convertir nun tipu de datos únicu. Les condiciones por que un tipu de datos T seya *declaráu completu* son *a les traces* les siguientes:

* Ye posible al momentu de compilación conocer l'espaciu acomuñáu al tipu de datos (esto ye, el compilador tien de conocer la resultancia de sizeof(T)).
* T Tien siquier un constructor, y un destructor, *bien declaraos*.
* Si T ye un tipu compuestu, o ye una clase derivada, o ye la especificación d'una plantía, o cualquier combinación de les anteriores, entós los dos condiciones establecíes primeramente tienen d'aplicar pa cada tipu de datu constituyente.

Polo xeneral, esto significa que cualquier tipu de datos definíu faciendo usu de les cabeceres completes, ye un tipu de datos completu.

En particular, y, a diferencia de lo qu'asocedía en C, **los tipos definíos per mediu de <tt>struct</tt> o <tt>enum</tt> son tipos completos**. Como tales, agora son suxetos a sobrecarga, conversiones implícites, etcétera.

Los **tipos numberaos**, entós, yá nun son a cencielles alies pa tipos enteros, sinón que son tipos de datos únicos en C++. El tipu de datos **bool**, igualmente, pasa a ser un tipu de datos únicu, ente qu'en C funcionaba en dellos casos como un alies pa dalguna clase de datu de tipu enteru.

## Compiladores
Unu de los compiladores llibres de C++ ye'l de GNU, el compilador G++ (parte del proyeutu GCC, que engloba dellos compiladores pa distintos llinguaxes). Otros compiladores comunes son Intel C++ Compiler, el compilador de Xcode, el compilador de Borland C++, el compilador de CodeWarrior C++, el compilador g++ de Cygwin, el compilador g++ de MinGW, el compilador de Visual C++, Carbide.c++, ente otros.

## Exemplu: Cmd con colores
Pa camudar el color de la interfaz del programa precisa la llibrería "cstdlib". la so aplicación sirve pa camudar el color de fondu del cmd y el color de les lletres.
Nota: Esto namái funciona en sistema Windows,

### Usu

```cpp
#include <cstdlib>
using namespace std;

system("color 45");
```


Nesti casu definióse'l fondu de pantalla de color coloráu y les lletres rosadas.

## Redolaes de desenvolvimientu

### So Microsoft Windows
* Visual Studio Code
* 
* Dev-C++
* Visual C++
* wxDev-C++
* Zinjai
* Open Watcom (IDE y Dialog Editor)
* CodeLite

### So MacOS
* Xcode
* Zinjai
* CodeLite
* Geany

### So DOS
* Turbo C, reemplazáu por C++Builder

### So GNU/Linux
* 
* NetBeans
* Eclipse
* Geany
* Emacs
* Zinjai
* Kdevelop
* Open Watcom (IDE y Dialog Editor)
* CodeLite
* Clion (software)

## Crítiques
A pesar de la so adopción xeneralizada, munchos programadores criticaron el llinguaxe C ++, incluyendo Linus Torvalds, Richard Stallman, y Ken Thompson. Los problemes inclúin una falta de reflexón o pañador de basura, tiempos de compilación lentos, perceived feature creep, y mensaxes d'error detallaos, particularmente de la metaprogramación de plantía.

Pa evitar los problemes qu'esisten en C ++, y p'aumentar la productividá, delles persones suxeren llinguaxes alternativos más recién que C ++, como D, Go, Rust y Vala.

## Ver tamién
* A++
* C++/CX
* C++11
* C++14
* C++17

## Referencies

### Bibliografía
* Bjarne Stroustrup, *El llinguaxe de programación C++*, Addison Wesley, Madrid, 1998, ISBN 84-7829-019-2
* Bjarne Stroustrup, *The C++ Programming Language*, Addison-Wesley Pub Co; Tercer edición (15 de febreru de 2000); ISBN 0-201-70073-5
* Bjarne Stroustrup, *The Design and Evolution of C++*, Addison-Wesley Pub Cp; Primer edición (29 de marzu de 1994); ISBN 0-201-54330-3
* Margaret A. Ellis y Bjarne Stroustrup, *The Annotated C++ Reference Manual*, Addison-Wesley Pub Co; (1 de xineru de 1990); ISBN 0-201-51459-1

## Enllaces esternos

* 
* 
*Happy Codings  Programming Code Examples