Está en la página 1de 12

C++

C++ es un lenguaje de programación diseñado a media- ciendo al compilador que usaremos el espacio de nombres
dos de los años 1980 por Bjarne Stroustrup. La intención std por lo que no tendremos que incluirlo cuando usemos
de su creación fue el extender al exitoso lenguaje de pro- elementos de este espacio de nombres, como pueden ser
gramación C con mecanismos que permitan la manipula- los objetos cout y cin, que representan el flujo de salida
ción de objetos. En ese sentido, desde el punto de vista de estándar (típicamente la pantalla o una ventana de texto)
los lenguajes orientados a objetos, el C++ es un lenguaje y el flujo de entrada estándar (típicamente el teclado).
híbrido. La definición de funciones es igual que en C, salvo por la
Posteriormente se añadieron facilidades de programación característica de que si main no va a recoger argumentos,
genérica, que se sumó a los otros dos paradigmas que no tenemos por qué ponérselos, a diferencia de C, donde
ya estaban admitidos (programación estructurada y la había que ponerlos explícitamente, aunque no se fueran a
programación orientada a objetos). Por esto se suele decir
usar. Queda solo comentar que el símbolo << se conoce
que el C++ es un lenguaje de programación multiparadig- como operador de inserción, y grosso modo está envian-
ma. do a cout lo que queremos mostrar por pantalla para que
Actualmente existe un estándar, denominado ISO C++, lo pinte, en este caso la cadena “Hola mundo”. El mis-
al que se han adherido la mayoría de los fabricantes de mo operador << se puede usar varias veces en la misma
compiladores más modernos. Existen también algunos in- sentencia, de forma que gracias a esta característica po-
térpretes, tales como ROOT. dremos concatenar el objeto endl al final, cuyo resultado
será imprimir un retorno de línea.
Una particularidad del C++ es la posibilidad de redefi-
nir los operadores, y de poder crear nuevos tipos que se Por último tomaremos una secuencia de caracteres del
teclado hasta el retorno de línea (presionando ENTER),
comporten como tipos fundamentales.
llamando al método get del objeto cin.
El nombre C++ fue propuesto por Rick Mascitti en el año
1983, cuando el lenguaje fue utilizado por primera vez
fuera de un laboratorio científico. Antes se había usado
el nombre “C con clases”. En C++, la expresión “C++"
2 Tipos de datos
significa “incremento de C” y se refiere a que C++ es una
extensión de C. C++ tiene los siguientes tipos fundamentales:

• Caracteres: char (también es un entero), wchar_t

1 Un ejemplo de programa • Enteros: short, int, long, long long

• Números en coma flotante: float, double, long double


A continuación se cita un programa de ejemplo Hola
mundo escrito en C++: • Booleanos: bool
/* Esta cabecera permite usar los objetos que encapsulan • Vacío: void
los descriptores stdout y stdin: cout(<<) y cin(>>)*/
#include <iostream> using namespace std; int main() {
cout << “Hola mundo” << endl; cin.get(); } El modificador unsigned se puede aplicar a enteros para
obtener números sin signo (por omisión los enteros con-
tienen signo), con lo que se consigue un rango mayor de
Al usar la directiva #include estamos diciéndole al com- números naturales.
pilador que busque e interprete todos los elementos de-
finidos en el archivo que acompaña la directiva (en este
caso, iostream). Para evitar sobrescribir los elementos ya 2.1 Tamaños asociados
definidos al ponerles igual nombre, se crearon los espa-
cios de nombres o namespace del singular en inglés. En Según la máquina y el compilador que se utilice los ti-
este caso hay un espacio de nombres llamado std, que es pos primitivos pueden ocupar un determinado tamaño en
donde se incluyen las definiciones de todas las funciones memoria. La siguiente lista ilustra el número de bits que
y clases que conforman la biblioteca estándar de C++. ocupan los distintos tipos primitivos en la arquitectura
Al incluir la sentencia using namespace std le estamos di- x86.

1
2 2 TIPOS DE DATOS

Otras arquitecturas pueden requerir distintos tamaños de int funcion (void);


tipos de datos primitivos. C++ no dice nada acerca de cuál
es el número de bits en un byte, ni del tamaño de estos Aunque la tendencia actual es la de no colocar la palabra
tipos; más bien, ofrece solamente las siguientes “garantías “void”.
de tipos":
Además se utiliza para determinar que una función no
• De acuerdo al estándar C99, un tipo char debe ocu- retorna un valor, como en:
par exactamente un byte compuesto de un mínimo void funcion (int parametro);
de 8 bits independientemente de la arquitectura de
la máquina.
Cabe destacar que void no es un tipo. Una función como
• El tamaño reconocido de char es de 1. Es decir, si- la declarada anteriormente no puede retornar un valor por
zeof(char) siempre devuelve 1. medio de return: la palabra clave va sola. No es posible
una declaración del tipo:
• Un tipo short tiene al menos el mismo tamaño que
void t; //Está mal
un tipo char.
• Un tipo long tiene al menos el doble tamaño en bytes En este sentido, void se comporta de forma ligeramente
que un tipo short. diferente a como lo hace en C, especialmente en cuanto a
• Un tipo int tiene un tamaño entre el de short y el de su significado en declaraciones y prototipos de funciones.
long, ambos inclusive, preferentemente el tamaño de Sin embargo, la forma especial void * indica que el tipo
un apuntador de memoria de la máquina. de datos es un puntero. Por ejemplo:
• Un tipo unsigned tiene el mismo tamaño que su ver- void *memoria;
sión signed.
Indica que memoria es un puntero a alguna parte, donde
se guarda información de algún tipo. El programador es
2.2 Wchar_t
responsable de definir estos “algún”, eliminando toda am-
bigüedad. Una ventaja de la declaración "void *" es que
Para la versión del estándar que se publicó en 1998, se de-
puede representar a la vez varios tipos de datos, depen-
cidió añadir el tipo de dato wchar_t, que permite el uso de
diendo de la operación de cast escogida. La memoria que
caracteres UNICODE, a diferencia del tradicional char,
hemos apuntado en alguna parte, en el ejemplo anterior,
que contempla simplemente al código de caracteres AS-
bien podría almacenar un entero, un flotante, una cadena
CII extendido. A su vez, se ha definido para la mayoría
de texto o un programa, o combinaciones de éstos. Es res-
de las funciones y clases, tanto de C como de C++, una
ponsabilidad del programador recordar qué tipo de datos
versión para trabajar con wchar_t, donde usualmente se
hay y garantizar el acceso adecuado.
prefija el carácter w al nombre de la función (en ocasiones
el carácter es un infijo). Por ejemplo:

• strcpy - wstrcpy
• std::string - std::wstring
• std::cout - std::wcout 2.4 La palabra “NULL”

Cabe resaltar que en C se define wchar_t como: Además de los valores que pueden tomar los tipos ante-
typedef unsigned short wchar_t; riormente mencionados, existe un valor llamado NULL,
sea el caso numérico para los enteros, caracter para el ti-
po char, cadena de texto para el tipo string, etc. El valor
Mientras que en C++ es en sí mismo un tipo de dato.
NULL, expresa, por lo regular, la representación de una
Macro, asignada al valor “0”.
2.3 La palabra reservada “void” Tenemos entonces que:

La palabra reservada void define en C++ el concepto de void* puntero = NULL; int entero = NULL; bool
no existencia o no atribución de un tipo en una variable boleana = NULL; char caracter = NULL;
o declaración. Es decir, una función declarada como void
no devolverá ningún valor. Esta palabra reservada tam- El valor de las variables anteriores nos daría 0. A diferen-
bién puede usarse para indicar que una función no recibe cia de la variable “caracter”, que nos daría el equivalente
parámetros, como en la siguiente declaración: a NULL, '\0', para caracteres.
4.1 Constructores 3

3 Principios cambiar su comportamiento... esas son las funciones de la


clase.
Todo programa en C++ debe tener la función principal Este es otro ejemplo de una clase:
main() (a no ser que se especifique en tiempo de compi-
class Punto { //por defecto los miembros son 'private'
lación otro punto de entrada, que en realidad es la función
para que sólo se puedan modificar desde la propia clase.
que tiene el main())
private: // Variable miembro privada int id; protected:
int main() {} // Variables miembro protegidas int x; int y; public: //
Constructor Punto(); // Destructor ~Punto(); // Funcio-
La función principal del código fuente main debe tener nes miembro o métodos int ObtenerX(); int ObtenerY();
uno de los siguientes prototipos: };
int main()
int main(int argc, char** argv)
4.1 Constructores
Aunque no es estándar algunas implementaciones per-
miten Son unos métodos especiales que se ejecutan automática-
int main(int argc, char** argv, char** env) mente al crear un objeto de la clase. En su declaración no
se especifica el tipo de dato que devuelven, y poseen el
La primera es la forma por omisión de un programa que mismo nombre que la clase a la que pertenecen. Al igual
no recibe parámetros ni argumentos. La segunda forma que otros métodos, puede haber varios constructores so-
tiene dos parámetros: argc, un número que describe el nú- brecargados, aunque no pueden existir constructores vir-
mero de argumentos del programa (incluyendo el nombre tuales.
del programa mismo), y argv, un puntero a un array de Como característica especial a la hora de implementar un
punteros, de argc elementos, donde el elemento argv[i] constructor, justo después de la declaración de los pará-
representa el i-ésimo argumento entregado al programa. metros, se encuentra lo que se llama “lista de inicializa-
En el tercer caso se añade la posibilidad de poder acce- dores”. Su objetivo es llamar a los constructores de los
der a las variables de entorno de ejecución de la misma atributos que conforman el objeto a construir.
forma que se accede a los argumentos del programa, pero
Cabe destacar que no es necesario declarar un constructor
reflejados sobre la variable env.
al igual que un destructor, pues el compilador lo puede
El tipo de retorno de main es un valor entero int. Al fi- hacer, aunque no es la mejor forma de programar.
nalizar la función main, debe incluirse el valor de retorno
Tomando el ejemplo de la Clase Punto, si deseamos que
(por ejemplo, return 0;, aunque el estándar prevé sola-
cada vez que se cree un objeto de esta clase las coorde-
mente dos posibles valores de retorno: EXIT_SUCCESS
nadas del punto sean igual a cero podemos agregar un
y EXIT_FAILURE, definidas en el archivo cstdlib), o sa-
constructor como se muestra a continuación:
lir por medio de la función exit. Alternativamente puede
dejarse en blanco, en cuyo caso el compilador es respon- class Punto { public: float x; // Coordenadas del punto
sable de agregar la salida adecuada. float y; // Constructor Punto() : x(0), y(0){ // Inicializa-
mos las variables “x” e “y” } }; // Main para demostrar
el funcionamiento de la clase # include <iostream> //
4 El concepto de clase Esto nos permite utilizar “cout” using namespace std;
int main () { Punto MiPunto; // creamos un elemento de
la clase Punto llamado MiPunto cout << “Coordenada
Los objetos en C++ son abstraídos mediante una clase. X: " << MiPunto.x << endl; // mostramos el valor
Según el paradigma de la programación orientada a ob- acumulado en la variable x cout << “Coordenada Y: "
jetos un objeto consta de: << MiPunto.y << endl; // mostramos el valor acumulado
en la variable y getchar(); // le indicamos al progra-
1. Identidad, que lo diferencia de otros objetos (Nom- ma que espere al buffer de entrada (detenerse) return 0; }
bre que llevara la clase a la que pertenece dicho ob-
jeto).
Si compilamos y ejecutamos el anterior programa, obte-
2. Métodos o funciones miembro nemos una salida que debe ser similar a la siguiente:

3. Atributos o variables miembro Coordenada X: 0 Coordenada Y: 0


Existen varios tipos de constructores en C++:
Un ejemplo de clase que podemos tomar es la clase perro.
Cada perro comparte unas características (atributos). Su 1. Constructor predeterminado. Es el constructor
número de patas, el color de su pelaje o su tamaño son al- que no recibe ningún parámetro en la función. Si
gunos de sus atributos. Las funciones que lo hagan ladrar, no se definiera ningún constructor, el sistema pro-
4 4 EL CONCEPTO DE CLASE

porcionaría uno predeterminado. Es necesario para ejecución del programa. La invocación del destructor de
la construcción de estructuras y contenedores de la un objeto que vive en heap se realiza a través del operador
STL. delete o delete[] para arrays. Ejemplo:
2. Constructor de copia. Es un constructor que reci- int main() { int *unEntero = new int(12); //asignamos
be un objeto de la misma clase, y realiza una copia un entero en memoria heap con el valor 12 int *array-
de los atributos del mismo. Al igual que el predeter- DeEnteros = new int[25]; //asignamos memoria para
minado, si no se define, el sistema proporciona uno. 25 enteros(no estan inicializados) delete unEntero;
//liberamos la memoria que ocupaba unEntero delete[]
3. Constructor de conversión. Este constructor, reci- arrayDeEnteros; //liberamos la memoria ocupada por
be como único parámetro, un objeto o variable de arrayDeEnteros return 0; }
otro tipo distinto al suyo propio. Es decir, convierte
un objeto de un tipo determinado a otro objeto del
Si no se utilizara el operador delete y delete[] en ese ca-
tipo que estamos generando.
so, la memoria ocupada por unEntero y arrayDeEnteros
respectivamente, quedaría ocupada sin sentido. Cuando
Constructores + Memoria heap Un objeto creado de la una porción de memoria queda ocupada por una variable
forma que se vio hasta ahora, es un objeto que vive dentro que ya no se utiliza, y no hay forma de acceder a ella, se
del scope(las llaves { }) en el que fue creado. Para que un denomina un 'memory leak'. En aplicaciones grandes, si
objeto pueda seguir viviendo cuando se saque de el sco- ocurren muchos memory leaks, el programa puede ter-
pe en el que se creó, se lo debe crear en memoria heap. minar ocupando bastante más memoria RAM de la que
Para esto, se utiliza el operador new, el cual asigna memo- debería, lo que no es para nada conveniente. Es por esto,
ria para almacenar al objeto creado, y además llama a su que el manejo de memoria heap debe usarse consciente-
constructor(por lo que se le pueden enviar parámetros). mente.
El operador new se utiliza de la siguiente manera:
Existen dos tipos de destructores pueden ser públicos o
int main() { Punto *unPunto = new Punto(); //esto llama privados, según si se declaran:
al constructor que se describe más arriba delete unPunto;
//no hay que olvidarse de liberar la memoria ocupada
por el objeto(ver la sección destructores, más abajo) • Si es público se llama desde cualquier parte del pro-
return 0; } grama para destruir el objeto.

• Si es privado no se permite la destrucción del objeto


Además, con el operador new[] se pueden crear arrays por el usuario.
(colecciones o listas ordenadas) de tamaño dinámico:
Punto *asignar(int cuantos) { return new Punto[cuantos]; El uso de destructores es clave en el concepto de Adquirir
//asigna un array de 'cuantos’ puntos(se llama el cons- Recursos es Inicializar.
tructor que se muestra más arriba), y se retorna. }

4.3 Funciones miembro


4.2 Destructores Función miembro es aquella que está declarada en ámbito
de clase. Son similares a las funciones habituales, con la
Los destructores son funciones miembro especiales lla- salvedad de que el compilador realizara el proceso de De-
madas automáticamente en la ejecución del programa, y coración de nombre (Name Mangling en inglés): Cam-
por tanto no tienen por qué ser llamadas explícitamen- biará el nombre de la función añadiendo un identificador
te por el programador. Sus principales cometidos son: de la clase en la que está declarada, pudiendo incluir ca-
racteres especiales o identificadores numéricos. Este pro-
• Liberar los recursos computacionales que el objeto ceso es invisible al programador. Además, las funciones
de dicha clase haya adquirido en tiempo de ejecución miembro reciben implícitamente un parámetro adicional:
al expirar éste. El puntero this, que referencia al objeto que ejecuta la
función.
• Quitar los vínculos que pudiesen tener otros recursos
u objetos con éste. Las funciones miembro se invocan accediendo prime-
ro al objeto al cual refieren, con la sintaxis: myob-
Los destructores son invocados automáticamente al al- ject.mymemberfunction(), esto es un claro ejemplo de
canzar el flujo del programa el fin del ámbito en el que una función miembro.
está declarado el objeto. El único caso en el que se de- Caso especial es el de las funciones miembro estáticas.
be invocar explícitamente al destructor de un objeto, A pesar de que son declaradas dentro de la clase, con el
es cuando éste fue creado mediante el operador new, es uso de la palabra clave static no recibirán el puntero this.
decir, que éste vive en memoria heap, y no en la pila de Gracias a esto no es necesario crear ninguna instancia de
4.6 Espacios de nombres 5

la clase para llamar a esta función, sin embargo, sólo se ConcretaA : public Abstracta { public: int metodo() {
podrá acceder a los miembros estáticos de la clase da- //haz algo return foo () + 2; } }; class ConcretaB : public
do que estos no están asociados al objeto sino al tipo. Abstracta { public: int metodo() { //otra implementación
La sintaxis para llamar a esta función estática es myty- return baz () - 5; } };
pe::mystaticmember().
En el ejemplo, la clase ConcretaA es una implementación
de la clase Abstracta, y la clase ConcretaB es otra imple-
4.4 Plantillas
mentación. Debe notarse que el = 0 es la notación que
Las plantillas son el mecanismo de C++ para implantar emplea C++ para definir funciones virtuales puras.
el paradigma de la programación genérica. Permiten que
una clase o función trabaje con tipos de datos abstrac-
tos, especificándose más adelante cuales son los que se 4.6 Espacios de nombres
quieren usar. Por ejemplo, es posible construir un vector
genérico que pueda contener cualquier tipo de estructu- Una adición a las características de C son los espacios de
ra de datos. De esta forma se pueden declarar objetos de nombre (namespace en inglés), los cuales pueden descri-
la clase de este vector que contengan enteros, flotantes, birse como áreas virtuales bajo las cuales ciertos nombres
polígonos, figuras, fichas de personal, etc. de variable o tipos tienen validez. Esto permite evitar las
ocurrencias de conflictos entre nombres de funciones, va-
La declaración de una plantilla se realiza anteponiendo la riables o clases.
declaración template <typename A,....> a la declaración
de la estructura (clase, estructura o función) deseado. El ejemplo más conocido en C++ es el espacio de nom-
bres std::, el cual almacena todas las definiciones nue-
Por ejemplo: vas en C++ que difieren de C (algunas estructuras y fun-
template <typename T> T max(const T &x, const T &y) ciones), así como las funcionalidades propias de C++
{ return (x > y) ? x : y; //si x > y, retorna x, sino retorna y } (streams) y los componentes de la biblioteca STL.
Por ejemplo:
La función max() es un ejemplo de programación gené- # include <iostream> // Las funciones en esta cabecera
rica, y dados dos parámetros de un tipo T (que puede ser existen dentro del espacio de nombres std:: namespace
int, long, float, double, etc.) devolverá el mayor de ellos mi_paquete{ int mi_valor; }; int main() { int mi_valor =
(usando el operador >). Al ejecutar la función con pará- 3; mi_paquete::mi_valor = 4; std::cout << mi_valor <<
metros de un cierto tipo, el compilador intentará “calzar” '\n'; // imprime '3' std::cout << mi_paquete::mi_valor <<
la plantilla a ese tipo de datos, o bien generará un mensaje '\n'; // imprime '4' return 0; }
de error si fracasa en ese proceso.

Como puede verse, las invocaciones directas a mi_valor


4.4.1 Especialización darán acceso solamente a la variable descrita localmen-
te; para acceder a la variable del espacio de nombres
4.5 Clases abstractas mi_paquete es necesario acceder específicamente el espa-
cio de nombres. Un atajo recomendado para programas
En C++ es posible definir clases abstractas. Una clase abs- sencillos es la directiva using namespace, que permite ac-
tracta, o clase base abstracta (ABC), es una que está dise- ceder a los nombres de variables del paquete deseado en
ñada sólo como clase padre de las cuales se deben derivar forma directa, siempre y cuando no se produzca alguna
clases hijas. Una clase abstracta se usa para representar ambigüedad o conflicto de nombres.
aquellas entidades o métodos que después se implemen-
tarán en las clases derivadas, pero la clase abstracta en sí
no contiene ninguna implementación -- solamente repre- 4.7 Herencia
senta los métodos que se deben implementar. Por ello, no
es posible instanciar una clase abstracta, pero sí una clase Existen varios tipos de herencia entre clases en el lenguaje
concreta que implemente los métodos definidos en ella. de programación C++. Estos son:
Las clases abstractas son útiles para definir interfaces, es
decir, un conjunto de métodos que definen el compor-
tamiento de un módulo determinado. Estas definiciones 4.7.1 Herencia simple
pueden utilizarse sin tener en cuenta la implementación
que se hará de ellos. La herencia en C++ es un mecanismo de abstracción
creado para poder facilitar y mejorar el diseño de las cla-
En C++ los métodos de las clases abstractas se definen ses de un programa. Con ella se pueden crear nuevas cla-
como funciones virtuales puras. ses a partir de clases ya hechas, siempre y cuando tengan
class Abstracta { public: virtual int metodo() = 0; } class un tipo de relación especial.
6 4 EL CONCEPTO DE CLASE

En la herencia, las clases derivadas “heredan” los datos 4.7.2 Herencia múltiple
y las funciones miembro de las clases base, pudiendo las
clases derivadas redefinir estos comportamientos (poli- La herencia múltiple es el mecanismo que permite al pro-
morfismo) y añadir comportamientos nuevos propios de gramador hacer clases derivadas a partir, no de una sola
las clases derivadas. Para no romper el principio de en- clase base, sino de varias. Para entender esto mejor, pon-
capsulamiento (ocultar datos cuyo conocimiento no es ne- gamos un ejemplo: Cuando ves a quien te atiende en una
cesario para el uso de las clases), se proporciona un nuevo tienda, como persona que es, podrás suponer que puede
modo de visibilidad de los datos/funciones: “protected”. hablar, comer, andar, pero, por otro lado, como emplea-
Cualquier cosa que tenga visibilidad protected se com- do que es, también podrás suponer que tiene un jefe, que
portará como pública en la clase Base y en las que compo- puede cobrarte dinero por la compra, que puede devol-
nen la jerarquía de herencia, y como privada en las clases verte el cambio, etc. Si esto lo trasladamos a la progra-
que NO sean de la jerarquía de la herencia. mación sería herencia múltiple (clase empleado_tienda):
Antes de utilizar la herencia, nos tenemos que hacer una class Persona { ... Hablar(); Caminar(); ... }; class
pregunta, y si tiene sentido, podemos intentar usar esta je- Empleado { Persona jefe; int sueldo; Cobrar(); ... };
rarquía: Si la frase <claseB> ES-UN <claseA> tiene sen- class EmpleadoTienda: public Persona, Empleado { ...
tido, entonces estamos ante un posible caso de herencia AlmacenarStock(); ComprobarExistencias(); ... };
donde clase A será la clase base y clase B la derivada.
Ejemplo: clases Barco, Acorazado, Carguero, etc. Un Por tanto, es posible utilizar más de una clase para que
Acorazado ES-UN Barco, un Carguero ES-UN Barco, un otra herede sus características.
Trasatlántico ES-UN Barco, etc.
En este ejemplo tendríamos las cosas generales de un Bar-
4.8 Sobrecarga de operadores
co (en C++)
class Barco { protected: char* nombre; float peso; public: La sobrecarga de operadores es una forma de hacer
//Constructores y demás funciones básicas de barco }; polimorfismo. Es posible definir el comportamiento de un
operador del lenguaje para que trabaje con tipos de da-
tos definidos por el usuario. No todos los operadores de
y ahora las características de las clases derivadas, podrían
C++ son factibles de sobrecargar, y, entre aquellos que
(a la vez que heredan las de barco) añadir cosas propias
pueden ser sobrecargados, se deben cumplir condiciones
del subtipo de barco que vamos a crear, por ejemplo:
especiales. En particular, los operadores sizeof y :: no son
class Carguero: public Barco { // Esta es la manera de sobrecargables.
especificar que hereda de Barco private: float carga; //El
No es posible en C++ crear un operador nuevo.
resto de cosas }; class Acorazado: public Barco { private:
int numeroArmas; int Soldados; // El resto de cosas }; Los comportamientos de los operadores sobrecargados se
implementan de la misma manera que una función, salvo
que esta tendrá un nombre especial: Tipo de dato de de-
Por último, hay que mencionar que existen 3 clases de
volución operator<token del operador>(parámetros)
herencia que se diferencian en el modo de manejar la vi-
sibilidad de los componentes de la clase resultante: Los siguientes operadores pueden ser sobrecargados:

• Operadores Unarios
• Herencia publica (class Derivada: public Base ): Con
este tipo de herencia se respetan los comportamien- • Operador * (de indirección)
tos originales de las visibilidades de la clase Base en • Operador -> (de indirección)
la clase Derivada.
• Operador & (de dirección)
• Operador +
• Herencia privada (clase Derivada: private Base):
• Operador -
Con este tipo de herencia todo componente de la
clase Base, será privado en la clase Derivada (las • Operador ++
propiedades heredadas serán privadas aunque estas • Operador --
sean públicas en la clase Base)
• Operadores Binarios

• Herencia protegida (clase Derivada: protected Ba- • Operador ==


se): Con este tipo de herencia, todo componente pú- • Operador +
blico y protegido de la clase Base, será protegido en
la clase Derivada, y los componentes privados, si- • Operador -
guen siendo privados. • Operador *
7

• Operador / STL (Standard Template Library), propia del lenguaje.


• Operador % Proporciona una serie plantillas (templates) que permi-
ten efectuar operaciones sobre el almacenado de datos,
• Operador << procesado de entrada/salida.
• Operador >>
• Operador &
• Operador ^ 6 Biblioteca de entrada y salida
• Operador |
Las clases basic_ostream y basic_stream, y los obje-
• Operador [] tos cout y cin, proporcionan la entrada y salida están-
• Operador () dar de datos (teclado/pantalla). También está disponible
cerr, similar a cout, usado para la salida estándar de erro-
• Operadores de Asignación res. Estas clases tienen sobrecargados los operadores <<
• Operador = y >>, respectivamente, con el objeto de ser útiles en la
inserción/extracción de datos a dichos flujos. Son opera-
• Operador +=
dores inteligentes, ya que son capaces de adaptarse al ti-
• Operador -= po de datos que reciben, aunque tendremos que definir el
• Operador *= comportamiento de dicha entrada/salida para clases/tipos
de datos definidos por el usuario. Por ejemplo:
• Operador /=
• Operador %= ostream& operator<<(ostream& fs, const Punto&
punto) { return fs << punto.x << ",” << punto.y; }
• Operador <<=
• Operador >>= De esta forma, para mostrar un punto, solo habría que
• Operador &= realizar la siguiente expresión:
• Operador ^= //... Punto p(4,5); //... cout << “Las coordenadas son: "
• Operador |= << p << endl; //...

Dado que estos operadores son definidos para un tipo de Es posible formatear la entrada/salida, indicando el nú-
datos definido por el usuario, éste es libre de asignarles mero de dígitos decimales a mostrar, si los textos se pasa-
cualquiera semántica que desee. Sin embargo, se consi- rán a minúsculas o mayúsculas, si los números recibidos
dera de primera importancia que las semánticas sean tan están en formato octal o hexadecimal, etc.
parecidas al comportamiento natural de los operadores
como para que el uso de los operadores sobrecargados
sea intuitivo. Por ejemplo, el uso del operador unario - 6.1 Fstreams
debiera cambiar el “signo” de un “valor”.
Tipo de flujo para el manejo de ficheros. La definición
Los operadores sobrecargados no dejan de ser funciones,
previa de ostreams/istreams es aplicable a este apartado.
por lo que pueden devolver un valor, si este valor es del
Existen tres clases (ficheros de lectura, de escritura o de
tipo de datos con el que trabaja el operador, permite el
lectura/escritura): ifstream,ofstream y fstream.
encadenamiento de sentencias. Por ejemplo, si tenemos
3 variables A, B y C de un tipo T y sobrecargamos el Como abrir un fichero: (nom-
operador = para que trabaje con el tipo de datos T, hay bre_variable_fichero).open(“nombre_fichero.dat/txt”,ios::in);
dos opciones: si el operador no devuelve nada una senten- para abrirlo en modo lectura. (nombrevariablefiche-
cia como “A=B=C;" (sin las comillas) daría error, pero si ro).open(“nombre_fichero.dat/txt”,ios::out); para abrirlo
se devuelve un tipo de datos T al implementar el opera- en modo escritura.
dor, permitiría concatenar cuantos elementos se quisie- Ejemplo: f.open(“datos.txt”,ios::in);
ran, permitiendo algo como “A=B=C=D=...;"
Como cerrar el fichero: nombre_variable_fichero.close();
Ejemplo: f.close();
5 Standard Template Library Leer un fichero:
(STL) 1-Si es fichero de texto plano:
#include <fstream> #include <string> #include <ios-
Los lenguajes de programación suelen tener una serie tream> using namespace std; int main() { ifstream
de bibliotecas de funciones integradas para la manipu- entrada; entrada.open(“textoPlano.txt”); string unString;
lación de datos a nivel más básico. En C++, además de while(entrada >> unString) cout << “Lei: " << unString
poder usar las bibliotecas de C, se puede usar la nativa << endl; return 0; }
8 6 BIBLIOTECA DE ENTRADA Y SALIDA

2-Si es un fichero binario(.dat); nom- Para añadir elementos al final del vector, se utiliza el mé-
bre_variable_fichero.read((char*)&nombre_variable, todo push_back(const T&). Por otro lado, para eliminar
sizeof(tipo_variable)); Ejemplo: f.read((char*)&e, un elemento del final del vector, se debe usar el método
sizeof(int)); pop_back().
Escribir un fichero: #include <vector> //libreria que contiene a la clase
1-Si es fichero de texto(.txt): nombrevariable<<"texto"; vector #include <iostream> using namespace std; int
main() { vector<int> intVector; //crea un vector de en-
donde “texto” puede ser también una variable de
cualquier tipo primitivo, o un string. Ejemplo: teros(sin elementos) intVector.push_back(25); //agrega
f<<HOLA; 2-Si es un fichero binario(.dat); nom- el entero 25 al vector cout << “El primer elemento
bre_variable_fichero.write((char*)&nombre_variable, es: " << intVector.front() << " y mi vector tiene " <<
sizeof(tipo_variable)); Ejemplo: f.write((char*)&e, intVector.size() << " elementos.” << endl; //imprime
sizeof(int)); el primer elemento(retornado por el método front()
intVector.push_back(32); //agrego el entero 32 al vector
Pueden abrirse pasando al constructor los parámetros re- cout << “El primer elemento es: " << intVector[0] <<
lativos a la ubicación del fichero y el modo de apertura: endl; //imprime 25 intVector.pop_back(); //elimina el
ultimo elemento del vector(osea 32) cout << “Ahora
tengo: " << intVector.size() << " elementos.” << endl;
6.2 Sstreams //imprimirá 1 return 0; }
Se destacan dos clases, ostringstream e istringstream.
Todo lo anteriormente dicho es aplicable a estas clases.
• Colas dobles: son parecidas a los vectores, pero tie-
Tratan a una cadena como si de un flujo de datos se tra-
nen mejor eficiencia para agregar o eliminar ele-
tase. ostringstream permite elaborar una cadena de texto
mentos en las “puntas”.deque<tipo_de_dato> nom-
insertando datos cual flujo, e istringstream puede extraer
bre_de_la_cola;
la información contenida en una cadena (pasada como
parámetro en su constructor) con el operador >>. Ejem-
Además de los métodos push_back(const T&) y
plos:
pop_back(), se agregan los métodos push_front(const
ostringstream s; s << nombre << ",” << edad << ",” T&) y pop_front(), que realizan lo mismo que los ya
<< estatura << ",” << punto(5,6) << endl; cout << explicados, pero en el comienzo de la cola.
s.str(); istringstream s(cadena); s >> nombre >> edad >>
#include <deque> //libreria de deques using na-
estatura >> p;
mespace std; int main() { deque<int> intDeque;
intDeque.push_front(25); intDeque.push_back(12);
while(intDeque.size()) intDeque.pop_back(); //borra
6.3 Contenedores todos los elementos return 0; }

Son clases plantillas especiales utilizadas para almacenar


tipos de datos genéricos, sean cuales sean. Todos los con- • Listas: Son eficientes a la hora de agregar elemen-
tenedores son homogéneos, es decir, una vez que se de- tos. La diferencia con las colas dobles, es que son
claran para contener un tipo de dato determinado, en ese más eficientes para eliminar elementos que no estén
contenedor, solo se podrán meter elementos de ese tipo. en alguna de las “puntas"list<tipo_de_dato> nom-
Según la naturaleza del almacenado, disponemos de va- bre_de_la_lista;
rios tipos:
• Adaptadores de secuencia.

• Vectores: Se definen por vector<tipo_de_dato> • Contenedores asociativos: map y multimap, que per-
nombre_del_vector; Son arrays (o listas ordenadas) miten asociar una “clave” con un “valor”. map no
que se redimensionan automáticamente al agregar permite valores repetidos, mientras que multimap
nuevos elementos, por lo que se le pueden agre- si.
gar “teóricamente”, infinitos elementos. Los vecto-
res nos permiten acceder a cualquier elemento que map<tipo_de_llave, tipo_de_dato> nombre_del_map;
contenga, mediante el operador[]. Debe tenerse en multimap<tipo_de_llave, tipo_de_dato> nom-
cuenta que si se intenta acceder a una posición que bre_del_multimap;
excede los límites del vector, este no hará ningún #include <map> //libreria que contiene a map y mul-
chequeo, por lo que se debe ser cuidadoso al utili- timap #include <string> //libreria de strings #include
zar este operador. Para asegurar un acceso seguro al <iostream> //libreria de entrada/salida using namespace
vector, se puede utilizar el método at(int), que lanza std; int main() { map<int, string> intAString; intAS-
una excepción de tipo std::out_of_range en caso de tring[1] = “uno"; intAString[10] = “diez"; cout << “En
que esto ocurra. intAString[1]: " << intAString[1] << endl; cout << “En
9

intAString[10]: " << intAString[10] << endl; return 0; } la misma manera. */ }

Entre las funciones más conocidas están swap (variable1,


• Contenedores asociativos: set y multiset, que ofre- variable2), que simplemente intercambia los valores de
cen solamente la condición de “pertenencia”, sin la variable1 y variable2; max (variable1, variable2) y su sí-
necesidad de garantizar un ordenamiento particular mil min (variable1, variable2), que retornan el máximo
de los elementos que contienen. o mínimo entre dos valores; find (inicio, fin, valor) que
busca valor en el espacio de variables entre inicio y fin;
etcétera.
6.4 Iteradores
Los algoritmos son muy variados, algunos incluso tienen
versiones específicas para operar con ciertos iteradores o
Pueden considerarse como una generalización de la clase
contenedores, y proveen un nivel de abstracción extra que
de “puntero”. Un iterador es un tipo de dato que permi-
permite obtener un código más “limpio”, que “describe”
te el recorrido y la búsqueda de elementos en los con-
lo que se está haciendo, en vez de hacerlo paso a paso
tenedores. Como las estructuras de datos (contenedores)
explícitamente.
son clases genéricas, y los operadores (algoritmos) que
deben operar sobre ellas son también genéricos (funcio-
nes genéricas), Stepanov y sus colaboradores tuvieron que
desarrollar el concepto de iterador como elemento o nexo 7 C++11
de conexión entre ambos. El nuevo concepto resulta ser
una especie de punteros que señalan a los diversos miem- El 12 de agosto de 2011, Herb Sutter, presidente del co-
bros del contenedor (punteros genéricos que como tales mité de estándares de C++, informó la aprobación uná-
no existen en el lenguaje). nime del nuevo estándar.[2] La publicación del mismo se
espera para algún momento de 2011.
Entre las características del nuevo estándar se pueden
6.5 Algoritmos destacar:
Combinando la utilización de templates y un estilo espe-
cífico para denotar tipos y variables, la STL ofrece una • Funciones lambda;
serie de funciones que representan operaciones comunes, • Referencias rvalue;
y cuyo objetivo es “parametrizar” las operaciones en que
estas funciones se ven involucradas de modo que su lec- • La palabra reservada auto;
tura, comprensión y mantenimiento, sean más fáciles de
realizar. • Inicialización uniforme;
Un ejemplo es la función copy, la cual simplemente copia • Plantillas con número variable de argumentos.
variables desde un lugar a otro. Más estrictamente, copia
los contenidos cuyas ubicaciones están delimitadas por Además se ha actualizado la biblioteca estándar del len-
dos iteradores, al espacio indicado por un tercer iterador. guaje.
La sintaxis es:
copy (inicio_origen, fin_origen, inicio_destino);
De este modo, todos los datos que están entre ini- 8 Diferencias de tipos respecto a C
cio_origen y fin_origen, excluyendo el dato ubicado en
este último, son copiados a un lugar descrito o apuntado En C++, cualquier tipo de datos que sea declarado com-
por inicio_destino. pleto (fully qualified, en inglés) se convierte en un tipo de
Un algoritmo muy importante que viene implementado datos único. Las condiciones para que un tipo de datos T
en la biblioteca STL, es el sort. El algoritmo sort, orde- sea declarado completo son a grandes rasgos las siguien-
na cualquier tipo de contenedor, siempre y cuando se le tes:
pasen como argumentos, desde donde y hasta donde se
quiere ordenarlo. • Es posible al momento de compilación conocer el
espacio asociado al tipo de datos (es decir, el com-
#include <vector> #include <deque> #include <al-
pilador debe conocer el resultado de sizeof(T)).
gorithm> int main() { vector<int> intVector; int-
Vector.push_back(60); intVector.push_back(12); • T Tiene al menos un constructor, y un destructor,
intVector.push_back(54); //para este momento, el vector bien declarados.
tiene 60,12,54 sort(intVector.begin(), intVector.end());
//listo, array ordenado, ahora tiene 12,54,60 /*Notar que • Si T es un tipo compuesto, o es una clase derivada,
si en vez de un vector, fuese una deque, se ordenaria de o es la especificación de una plantilla, o cualquier
10 13 ENLACES EXTERNOS

combinación de las anteriores, entonces las dos con- 11.2 Bajo MacOS
diciones establecidas previamente deben aplicar pa-
ra cada tipo de dato constituyente. • Xcode

En general, esto significa que cualquier tipo de datos defi- • Zinjai


nido haciendo uso de las cabeceras completas, es un tipo
de datos completo.
11.3 Bajo DOS
En particular, y, a diferencia de lo que ocurría en C, los
tipos definidos por medio de struct o enum son tipos • Turbo C, reemplazado por C++Builder
completos. Como tales, ahora son sujetos a sobrecarga,
conversiones implícitas, etcétera.
Los tipos enumerados, entonces, ya no son simplemente 11.4 Bajo GNU/Linux
alias para tipos enteros, sino que son tipos de datos úni-
cos en C++. El tipo de datos bool, igualmente, pasa a ser • Code::Blocks
un tipo de datos único, mientras que en C funcionaba en
• NetBeans
algunos casos como un alias para alguna clase de dato de
tipo entero. • Eclipse

• Geany
9 Compiladores • Zinjai

Uno de los compiladores libres de C++ es el de GNU, el • Kdevelop


compilador G++ (parte del proyecto GCC, que engloba
varios compiladores para distintos lenguajes). Otros com-
piladores comunes son Intel C++ Compiler, el compila-
dor de Xcode, el compilador de Borland C++, el compila-
12 Referencias
dor de CodeWarrior C++, el compilador g++ de Cygwin,
[1] Stroustrup, Bjarne (1997). «1». The C++ Programming
el compilador g++ de MinGW, el compilador de Visual
Language (Third edición). ISBN 0201889544. OCLC
C++, Carbide.c++, entre otros.
59193992.

[2] http://herbsutter.com/2011/08/12/
10 Ejemplo: Cmd con colores we-have-an-international-standard-c0x-is-unanimously-approved/

Para cambiar el color de la interfaz del programa se nece-


sita la libreria “stdlib.h”. su aplicacion sirve para cambiar
12.1 Bibliografía
el color de fondo del cmd y el color de las letras.
• Bjarne Stroustrup, El lenguaje de programación
C++, Addison Wesley, Madrid, 1998, ISBN 84-
Uso #include <stdlib.h> using namespace std; sys- 7829-019-2
tem(“color 45”);
• Bjarne Stroustrup, The C++ Programming Langua-
ge, Addison-Wesley Pub Co; Tercera edición (15 de
En este caso se ha definido el fondo de pantalla de color febrero de 2000); ISBN 0-201-70073-5
rojo y las letras rosadas.
• Bjarne Stroustrup, The Design and Evolution of
C++, Addison-Wesley Pub Cp; Primera edición (29
11 Entornos de desarrollo de marzo de 1994); ISBN 0-201-54330-3

• Margaret A. Ellis y Bjarne Stroustrup, The Anno-


11.1 Bajo Microsoft Windows tated C++ Reference Manual, Addison-Wesley Pub
Co; (1 de enero de 1990); ISBN 0-201-51459-1
• Code::Blocks
• Dev-C++
• Visual C++
13 Enlaces externos
• wxDev-C++
• Wikimedia Commons alberga contenido multi-
• Zinjai media sobre C++. Commons
11

• plantillas en c++ tutorial para principiantes sobre


plantillas
• cplusplus resources (en inglés)

• C/C++ Reference
• C/C++ Programming

• Inline::CPP Módulo Perl en CPAN para programar


en C++ dentro de programas Perl (en inglés)

• Curso de C++ Completo curso de C++ gratuito, en


castellano, que además de referencia, también inclu-
ye explicaciones sencillas para aprender el lenguaje
de programación

• Pensar en C++ Traducción al castellano del libro de


Bruce Eckel: “Thinking in C++"
• C++ paso a paso Libro que explica paso a paso los
conceptos de programación orientada a objetos del
lenguaje C++
12 14 TEXT AND IMAGE SOURCES, CONTRIBUTORS, AND LICENSES

14 Text and image sources, contributors, and licenses


14.1 Text
• C++ Fuente: http://es.wikipedia.org/wiki/C%2B%2B?oldid=77909538 Colaboradores: AstroNomo, Macar, Centeno, Joseaperez, Pa-
blo.cl, Sauron, JorgeGG, ManuelGR, Nonick, Angus, Sanbec, Zwobot, Comae, Javier Carro, Gauss, Dodo, Stoni, Levhita, Triku, As-
cánder, Sms, Rsg, Tostadora, Elwikipedista, Robotito, Alejovivasp, Vargenau, JCCO, Toad32767, Panchurret, Niqueco, Renabot, Boti-
cario, Zeioth, Petronas, Hispa, Edub, Taichi, Rembiapo pohyiete (bot), Kitalphar, Edtruji, Neuron, OMenda, Orgullobot, RobotQuistnix,
Tranchis, Adept, Francosrodriguez, Alhen, LC0, Superzerocool, Chobot, Yrbot, BOT-Superzerocool, Oscar ., FlaBot, Vitamine, BOTijo,
.Sergio, YurikBot, Mortadelo2005, Ivancp, Icvav, GermanX, Zam, Beto29, KnightRider, Hanzo86, Jesuja, Eduardo Lima, SDaniel, Ban-
field, Hxxbin, George McFinnigan, Maldoror, Er Komandante, Lasneyx, KocjoBot, Tomatejc, FIAL NV JAIOVO JP;S J, Niuweme, Ivan
rome, Futbolero, Jstitch, BOTpolicia, Ludoviko, CEM-bot, Jorgelrm, Damifb, Tute, Wfox, Ginta, Laura Fiorucci, Marc-André Aßbrock,
EnWILLYado, X.Cyclop, Jjvaca, Retama, Anonimato1990, Cristianrock2, Clavec, Mcetina, Montgomery, FrancoGG, Thijs!bot, Pablo-
Castellano, RamiroGonzalezMaciel, Escarbot, JoaquinFerrero, Zcool, Fernando.a.gomez.f, Isha, Xoneca, Mpeinadopa, JAnDbot, Scmbg,
Muro de Aguas, TXiKiBoT, ColdWind, Humberto, Netito777, Bedorlan, Jucamo, Shark-0106, Vcamacho, KanTagoff, Pólux, BL, Sebado,
Biasoli, Ia027, AlnoktaBOT, Dusan, Cinevoro, Skyhack, VolkovBot, Drever, Snakeyes, Technopat, Galandil, Josell2, Matdrodes, Black-
Beast, Shooke, Lucien leGrey, AlleborgoBot, Calin99, Muro Bot, Numbo3, Obazavil, SieBot, Onzalo, Danielba894, Ctrl Z, Carpem, Lo-
veless, Obelix83, A. B. 10, Hompis, A Vázquez O., Ermey, Belb, Maxvaz, Tirithel, Locos epraix, Jarisleif, HUB, Maximoarmijo, Piero71,
Nicop, DragonBot, Eduardosalg, Botellín, Sacel, Alejandrocaro35, Botito777, LordT, Darkicebot, Açipni-Lovrij, UA31, Arlm1000, AV-
BOT, David0811, Kona, LucienBOT, A ver, Skilltik, Gurulandio, Peti610bot, Diegusjaimes, Davidgutierrezalvarez, Linkcisco, Arjuno3,
Luckas-bot, Nallimbot, Roinpa, FariBOT, LordboT, S3b4s5, Joseagrc, Marioxcc, Wikante, 6d23, Marxto, NobelBot, SuperBraulio13,
Ortisa, Xqbot, Jkbw, DarkSulivan, Cally Berry, Botarel, Spyda72, Amgc56, White Master King, BOTirithel, TiriBOT, Nicolapedia, Ca-
ritdf, Halfdrag, Abece, Fitoschido, Edgardo C, PatruBOT, D4gnu, Alex3638, Strongilocentrotus, Foundling, DiegoBM, EmausBot, Savh,
ChessBOT, Sergio Andres Segovia, Adadon, Africanus, Genhuan, Grillitus, Arpabone, KLBot, UnRar, Emiduronte, Waka Waka, Rufflos,
Rezabot, KLBot2, AbelNightroad26, Cyberdelic, Francy lugo, J....441111, Ralgis, Eze 96ram, JoC2011, LordAlfonso, Carlos R Castro
G, Helmy oved, Flashlack, YFdyh-bot, Tsunderebot, CapacitorCapaz, 2rombos, Gjprada, Legobot, Rotciv1010, Vale Espin, Vmfdez90,
Alex9737, JacobRodrigues, Kirebyte, BenjaBot y Anónimos: 512

14.2 Images
• Archivo:C_plus_plus.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/5/5b/C_plus_plus.svg Licencia: Public domain Cola-
boradores: Trabajo propio Artista original: JTojnar
• Archivo:Commons-logo.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/4/4a/Commons-logo.svg Licencia: Public domain
Colaboradores: This version created by Pumbaa, using a proper partial circle and SVG geometry features. (Former versions used to be slightly
warped.) Artista original: SVG version was created by User:Grunt and cleaned up by 3247, based on the earlier PNG version, created by
Reidab.

14.3 Content license


• Creative Commons Attribution-Share Alike 3.0