Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
La
intenci�n de su creaci�n fue extender al lenguaje de programaci�n C mecanismos que
permiten la manipulaci�n de objetos. En ese sentido, desde el punto de vista de los
lenguajes orientados a objetos, el C++ es un lenguaje h�brido.
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++" significa "incremento de
C" y se refiere a que C++ es una extensi�n de C.
�ndice
1 Ejemplos
2 Tipos de datos
2.1 Tama�os asociados
2.2 Wchar_t
2.3 La palabra reservada "void"
2.4 La palabra "NULL"
3 Principios
4 El concepto de clase
4.1 Constructores
4.2 Destructores
4.3 Funciones miembro
4.4 Plantillas
4.4.1 Especializaci�n
4.5 Clases abstractas
4.6 Espacios de nombres
4.7 Herencia
4.7.1 Herencia simple
4.7.2 Herencia m�ltiple
4.8 Sobrecarga de operadores
5 Standard Template Library (STL)
6 Biblioteca de entrada y salida
6.1 Fstreams
6.2 Sstreams
6.3 Contenedores
6.4 Iteradores
6.5 Algoritmos
7 C++11
8 Actualidad y futuro
9 Diferencias de tipos respecto a C
10 Compiladores
11 Ejemplo: Cmd con colores
11.1 Uso
12 Entornos de desarrollo
12.1 Bajo Microsoft Windows
12.2 Bajo MacOS
12.3 Bajo DOS
12.4 Bajo GNU/Linux
13 Cr�ticas
14 V�ase tambi�n
15 Referencias
15.1 Bibliograf�a
16 Enlaces externos
Ejemplos
/* Esta cabecera permite usar los objetos que encapsulan los descriptores stdout
y stdin: cout(<<) y cin(>>)*/
#include <iostream>
int main()
{
cout << "Hola mundo" << endl;
return 0;
}
El modificador unsigned se puede aplicar a enteros para obtener n�meros sin signo
(por omisi�n los enteros contienen signo), con lo que se consigue un rango mayor de
n�meros naturales.
Tama�os asociados
Seg�n la m�quina y el compilador que se utilice los tipos primitivos pueden ocupar
un determinado tama�o en memoria. La siguiente lista ilustra el n�mero de bits que
ocupan los distintos tipos primitivos en la arquitectura x86.
Tama�os de tipos primitivos bajo i386 (GCC) Tipo N�mero de bits
char 8
short 16
int 32
float 32
double 64
Wchar_t
Para la versi�n del est�ndar que se public� en 1998, se decidi� a�adir el tipo de
dato wchar_t, que permite el uso de caracteres UNICODE, a diferencia del
tradicional char, que contempla simplemente al c�digo de caracteres ASCII
extendido. A su vez, se ha definido para la mayor�a de las funciones y clases,
tanto de C como de C++, una versi�n para trabajar con wchar_t, donde usualmente se
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
Adem�s se utiliza para determinar que una funci�n no retorna un valor, como en:
Sin embargo, la forma especial void * indica que el tipo de datos es un puntero.
Por ejemplo:
void *memoria;
Adem�s de los valores que pueden tomar los tipos anteriormente mencionados, existe
un valor llamado NULL, sea el caso num�rico para los enteros, car�cter para el tipo
char, cadena de texto para el tipo string, etc. El valor NULL, expresa, por lo
regular, la representaci�n de una Macro, asignada al valor "0".
Todo programa en C++ debe tener la funci�n principal main() (a no ser que se
especifique en tiempo de compilaci�n otro punto de entrada, que en realidad es la
funci�n que tiene el main())
int main()
{}
La funci�n principal del c�digo fuente main debe tener uno de los siguientes
prototipos:
int main()
int main(int argc, char** argv)
Los objetos en C++ son abstra�dos mediante una clase. Seg�n el paradigma de la
programaci�n orientada a objetos un objeto consta de:
Un ejemplo de clase que podemos tomar es la clase perro. Cada perro comparte unas
caracter�sticas (atributos). Su n�mero de patas, el color de su pelaje o su tama�o
son algunos de sus atributos. Las funciones que lo hagan ladrar, cambiar su
comportamiento... esas son las funciones de la clase.
class Punto
{
//por omisi�n, los miembros son 'private' para que solo se puedan modificar desde
la propia clase.
private:
// Variable miembro privada
int id;
protected:
// Variables miembro protegidas
int x;
int y;
public:
// Constructor
Punto();
// Destructor
~Punto();
// Funciones miembro o m�todos
int ObtenerX();
int ObtenerY();
};
Constructores
V�ase tambi�n: Constructor (inform�tica)
Tomando el ejemplo de la Clase Punto, si deseamos que cada vez que se cree un
objeto de esta clase las coordenadas del punto sean igual a cero podemos agregar un
constructor como se muestra a continuaci�n:
class Punto
{
public:
// Constructor
Punto() : x(0), y(0){ // Inicializamos las variables "x" e "y"
}
};
int main () {
Punto MiPunto; // creamos un elemento de la clase Punto llamado MiPunto
cout << "Coordenada X: " << MiPunto.x << endl; // mostramos el valor acumulado
en la variable x
cout << "Coordenada Y: " << MiPunto.y << endl; // mostramos el valor acumulado
en la variable y
getchar(); // le indicamos al programa que espere al buffer de entrada
(detenerse)
return 0;
}
Si compilamos y ejecutamos el anterior programa, obtenemos una salida que debe ser
similar a la siguiente:
Coordenada X: 0 Coordenada Y: 0
Constructores + Memoria heap Un objeto creado de la forma que se vio hasta ahora,
es un objeto que vive dentro del scope(las llaves { }) en el que fue creado. Para
que un objeto pueda seguir viviendo cuando se saque del scope en el que se cre�, se
lo debe crear en memoria heap. Para esto, se utiliza el operador new, el cual
asigna memoria para almacenar al objeto creado, y adem�s llama a su constructor(por
lo que se le pueden enviar par�metros). El operador new se utiliza de la siguiente
manera:
int main() {
Punto *unPunto = new Punto(); //esto llama 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)
return 0;
}
Destructores
V�ase tambi�n: Destructor (inform�tica)
int main() {
int *unEntero = new int(12); //asignamos un entero en memoria heap con el
valor 12
int *arrayDeEnteros = new int[25]; //asignamos memoria para 25 enteros(no est�n
inicializados)
delete unEntero; //liberamos la memoria que ocupaba unEntero
delete[] arrayDeEnteros; //liberamos la memoria ocupada por
arrayDeEnteros
return 0;
}
Funci�n miembro es aquella que est� declarada en �mbito de clase. Son similares a
las funciones habituales, con la salvedad de que el compilador realizara el proceso
de Decoraci�n de nombre (Name Mangling en ingl�s): Cambiar� el nombre de la funci�n
a�adiendo un identificador de la clase en la que est� declarada, pudiendo incluir
caracteres especiales o identificadores num�ricos. Este proceso es invisible al
programador. Adem�s, las funciones miembro reciben impl�citamente un par�metro
adicional: El puntero this, que referencia al objeto que ejecuta la funci�n.
Las funciones miembro se invocan accediendo primero al objeto al cual refieren, con
la sintaxis: myobject.mymemberfunction(), esto es un claro ejemplo de una funci�n
miembro.
Por ejemplo:
El siguiente ejemplo:
crea una plantilla bajo la cual pueden ser definidas en el c�digo de cabecera
cualesquiera funciones especializadas para un tipo de datos como int
myfunction(int), int myfunction(std::string), int myfunction(bool), etc�tera:
Cada una de estas funciones tiene su propia definici�n (cuerpo). Cada cuerpo
diferente, no equivalente ("no convertible") corresponde a una especializaci�n. Si
una de estas funciones no fuera definida, el compilador tratar� de aplicar las
conversiones de tipos de datos que le fuesen permitidas para "calzar" una de las
plantillas, o generar� un mensaje de error si fracasa en ese proceso.
En C++ es posible definir clases abstractas. Una clase abstracta, o clase base
abstracta (ABC), es una que est� dise�ada solo como clase padre de las cuales se
deben derivar clases hijas. Una clase abstracta se usa para representar aquellas
entidades o m�todos que despu�s se implementar�n en las clases derivadas, pero la
clase abstracta en s� no contiene ninguna implementaci�n -- solamente representa
los m�todos que se deben implementar. Por ello, no es posible instanciar una clase
abstracta, pero s� una clase concreta que implemente los m�todos definidos en ella.
Las clases abstractas son �tiles para definir interfaces, es decir, un conjunto de
m�todos que definen el comportamiento de un m�dulo determinado. Estas definiciones
pueden utilizarse sin tener en cuenta la implementaci�n que se har� de ellos.
En C++ los m�todos de las clases abstractas se definen como funciones virtuales
puras.
class Abstracta
{
public:
virtual int metodo() = 0;
}
class ConcretaA : public Abstracta
{
public:
int metodo()
{
//haz algo
return foo () + 2;
}
};
Por ejemplo:
# include <iostream>
// Las funciones en esta cabecera existen dentro del espacio de nombres std::
namespace mi_paquete{
int mi_valor;
};
int main()
{
int mi_valor = 3;
mi_paquete::mi_valor = 4;
return 0;
}
Como puede verse, las invocaciones directas a mi_valor dar�n acceso solamente a la
variable descrita localmente; para acceder a la variable del espacio de nombres
mi_paquete es necesario acceder espec�ficamente el espacio de nombres. Un atajo
recomendado para programas sencillos es la directiva using namespace, que permite
acceder a los nombres de variables del paquete deseado en forma directa, siempre y
cuando no se produzca alguna ambig�edad o conflicto de nombres.
Herencia
En la herencia, las clases derivadas "heredan" los datos y las funciones miembro de
las clases base, pudiendo las clases derivadas redefinir estos comportamientos
(polimorfismo) y a�adir comportamientos nuevos propios de las clases derivadas.
Para no romper el principio de encapsulamiento (ocultar datos cuyo conocimiento no
es necesario para el uso de las clases), se proporciona un nuevo modo de
visibilidad de los datos/funciones: "protected". Cualquier cosa que tenga
visibilidad protected se comportar� como p�blica en la clase Base y en las que
componen la jerarqu�a de herencia, y como privada en las clases que NO sean de la
jerarqu�a de la herencia.
Antes de utilizar la herencia, nos tenemos que hacer una pregunta, y si tiene
sentido, podemos intentar usar esta jerarqu�a: Si la frase <claseB> ES-UN <claseA>
tiene sentido, entonces estamos ante un posible caso de herencia donde clase A ser�
la clase base y clase B la derivada.
class Barco {
protected:
char* nombre;
float peso;
public:
//Constructores y dem�s funciones b�sicas de barco
};
y ahora las caracter�sticas de las clases derivadas, podr�an (a la vez que heredan
las de barco) a�adir cosas propias del subtipo de barco que vamos a crear, por
ejemplo:
Herencia p�blica (class Derivada: public Base ): Con este tipo de herencia se
respetan los comportamientos originales de las visibilidades de la clase Base en la
clase Derivada.
Herencia privada (clase Derivada: private Base): Con este tipo de herencia todo
componente de la clase Base, ser� privado en la clase Derivada (las propiedades
heredadas ser�n privadas aunque estas sean p�blicas en la clase Base)
Herencia protegida (clase Derivada: protected Base): Con este tipo de herencia,
todo componente p�blico y protegido de la clase Base, ser� protegido en la clase
Derivada, y los componentes privados, siguen siendo privados.
Herencia m�ltiple
class Persona {
...
Hablar();
Caminar();
...
};
class Empleado {
Persona jefe;
int sueldo;
Cobrar();
...
};
Por tanto, es posible utilizar m�s de una clase para que otra herede sus
caracter�sticas.
Sobrecarga de operadores
Operadores Unarios
Operador * (de indirecci�n)
Operador -> (de indirecci�n)
Operador & (de direcci�n)
Operador +
Operador -
Operador ++
Operador --
Operadores Binarios
Operador ==
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 ^=
Operador |=
Dado que estos operadores son definidos para un tipo de datos definido por el
usuario, este es libre de asignarles cualquiera sem�ntica que desee. Sin embargo,
se considera de primera importancia que las sem�nticas sean tan 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 - debiera
cambiar el "signo" de un "valor".
Los operadores sobrecargados no dejan de ser funciones, por lo que pueden devolver
un valor, si este valor es del tipo de datos con el que trabaja el operador,
permite el encadenamiento de sentencias. Por ejemplo, si tenemos 3 variables A, B y
C de un tipo T y sobrecargamos el operador = para que trabaje con el tipo de datos
T, hay dos opciones: si el operador no devuelve nada una sentencia como "A=B=C;"
(sin las comillas) dar�a error, pero si se devuelve un tipo de datos T al
implementar el operador, permitir�a concatenar cuantos elementos se quisieran,
permitiendo algo como "A=B=C=D=...;"
Standard Template Library (STL)
Art�culo principal: Standard Template Library
De esta forma, para mostrar un punto, solo habr�a que realizar la siguiente
expresi�n:
//...
Punto p(4,5);
//...
cout << "Las coordenadas son: " << p << endl;
//...
Ejemplo: f.close();
Leer un fichero:
#include <fstream>
#include <string>
#include <iostream>
Ejemplo:
f.read((char*)&e, sizeof(int));
Escribir un fichero:
Ejemplo: f<<HOLA;
Ejemplo:
f.write((char*)&e, sizeof(int));
ostringstream s;
s << nombre << "," << edad << "," << estatura << "," << punto(5,6) << endl;
cout << s.str();
istringstream s(cadena);
s >> nombre >> edad >> estatura >> p;
Contenedores
vector<tipo_de_dato> nombre_del_vector;
Son arrays (o listas ordenadas) que se redimensionan autom�ticamente al agregar
nuevos elementos, por lo que se le pueden agregar "te�ricamente", infinitos
elementos. Los vectores nos permiten acceder a cualquier elemento que contenga,
mediante el operador[]. Debe tenerse en cuenta que si se intenta acceder a una
posici�n que excede los l�mites del vector, este no har� ning�n chequeo, por lo que
se debe ser cuidadoso al utilizar este operador. Para asegurar un acceso seguro al
vector, se puede utilizar el m�todo at(int), que lanza una excepci�n de tipo
std::out_of_range en caso de que esto ocurra.
int main() {
vector<int> intVector; //crea un vector de enteros (sin elementos)
intVector.push_back(25); //agrega el entero 25 al vector
cout << "El primer elemento es: " << intVector.front() <<
" y mi vector tiene " << intVector.size() << " elementos." << endl; //imprime
el primer elemento, retornado por el m�todo front()
return 0;
}
Colas dobles: son parecidas a los vectores, pero tienen mejor eficiencia para
agregar o eliminar elementos en las "puntas".
deque<tipo_de_dato> nombre_de_la_cola;
int main() {
deque<int> intDeque;
intDeque.push_front(25);
intDeque.push_back(12);
while(intDeque.size())
intDeque.pop_back(); //borra todos los elementos
return 0;
}
Adaptadores de secuencia.
Contenedores asociativos: map y multimap, que permiten asociar una "clave" con
un "valor". map no permite valores repetidos, mientras que multimap si.
int main() {
map<int, string> intAString;
intAString[1] = "uno";
intAString[10] = "diez";
cout << "En intAString[1]: " << intAString[1] << endl;
cout << "En intAString[10]: " << intAString[10] << endl;
return 0;
}
Iteradores
De este modo, todos los datos que est�n entre inicio_origen y fin_origen,
excluyendo el dato ubicado en este �ltimo, son copiados a un lugar descrito o
apuntado por inicio_destino.
#include <vector>
#include <deque>
#include <algorithm>
int main() {
vector<int> intVector;
intVector.push_back(60);
intVector.push_back(12);
intVector.push_back(54); //para este momento, el vector tiene 60,12,54
sort(intVector.begin(), intVector.end()); //listo, array ordenado, ahora tiene
12,54,60
/*Notar que si en vez de un vector, fuese una deque, se ordenar�a de la misma
manera. */
}
Entre las funciones m�s conocidas est�n swap (variable1, variable2), que
simplemente intercambia los valores de variable1 y variable2; max (variable1,
variable2) y su s�mil min (variable1, variable2), que retornan el m�ximo o m�nimo
entre dos valores; find (inicio, fin, valor) que busca valor en el espacio de
variables entre inicio y fin; etc�tera.
Los algoritmos son muy variados, algunos incluso tienen versiones espec�ficas para
operar con ciertos iteradores o contenedores, y proveen un nivel de abstracci�n
extra que permite obtener un c�digo m�s "limpio", que "describe" lo que se est�
haciendo, en vez de hacerlo paso a paso expl�citamente.
C++11
Art�culo principal: C++11
Funciones lambda;
Referencias rvalue;
La palabra reservada auto;
Inicializaci�n uniforme;
Plantillas con n�mero variable de argumentos.
En C++, cualquier tipo de datos que sea declarado completo (fully qualified, en
ingl�s) se convierte en un tipo de datos �nico. Las condiciones para que un tipo de
datos T sea declarado completo son a grandes rasgos las siguientes:
En general, esto significa que cualquier tipo de datos definido haciendo uso de las
cabeceras completas, es un tipo de datos completo.
Los tipos enumerados, entonces, ya no son simplemente alias para tipos enteros,
sino que son tipos de datos �nicos en C++. El tipo de datos bool, igualmente, pasa
a ser un tipo de datos �nico, mientras que en C funcionaba en algunos casos como un
alias para alguna clase de dato de tipo entero.
Compiladores
Uno de los compiladores libres de C++ es el de GNU, el compilador G++ (parte del
proyecto GCC, que engloba varios compiladores para distintos lenguajes). 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++, entre otros.
Ejemplo: Cmd con colores
#include <cstdlib>
using namespace std;
system("color 45");
Bajo MacOS
Xcode
Zinjai
CodeLite
Geany
Bajo DOS
Bajo GNU/Linux
Code::Blocks
NetBeans
Eclipse
Geany
Emacs
Zinjai
Kdevelop
Open Watcom (IDE y Dialog Editor)
CodeLite
Clion (software)
Cr�ticas
Para evitar los problemas que existen en C ++, y para aumentar la productividad,8?
algunas personas sugieren lenguajes alternativos m�s recientes que C ++, como D,
Go, Rust y Vala.9?
V�ase tambi�n
A++
C++/CX
C++11
C++14
C++17
Referencias
Stroustrup, Bjarne (1997). �1�. The C++ Programming Language (Third edici�n). ISBN
0201889544. OCLC 59193992.
http://herbsutter.com/2011/08/12/we-have-an-international-standard-c0x-is-
unanimously-approved/
�Re: [RFC Convert builin-mailinfo.c to use The Better String Library]�, 6 de
septiembre de 2007, consultado el 31 de marzo de 2015.
�Re: Efforts to attract more users?�, 12 de julio de 2010, consultado el 31 de
marzo de 2015.
Andrew Binstock (18 de mayo de 2011). �Dr. Dobb's: Interview with Ken Thompson�.
Consultado el 7 de febrero de 2014.
Pike, Rob (2012). �Less is exponentially more�.
Kreinin, Yossi (13 de octubre de 2009). �Defective C++�. Consultado el 3 de febrero
de 2016.
New Languages, and Why We Need Them, MIT Technology Review
Bibliograf�a