thumb|Bjarne Stroustrup, creador de C++.
C++ es un lenguaje de programación diseñado en 1979 por Bjarne Stroustrup. La intención de su creación fue extender al lenguaje de programación C y añadir mecanismos que permiten la manipulación de objetos. En ese sentido, desde el punto de vista de los lenguajes orientados a objetos, C++ es un lenguaje híbrido.
Posteriormente se añadieron facilidades de programación genérica, que se sumaron a los paradigmas de programación estructurada y programación orientada a objetos. Por esto se suele decir que el C++ es un lenguaje de programación multiparadigma.
Actualmente existe un estándar, denominado ISO C++, al que se han adherido la mayoría de los fabricantes de compiladores más modernos. Existen también algunos intérpretes, tales como ROOT.
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.
Características de C++
Su sintaxis es heredada del lenguaje C. Programa orientado a objetos (POO o OOP por sus siglas en ingles). Permite la agrupación de instrucciones. Es portátil y tiene un gran número de compiladores en diferentes plataformas y sistemas operativos. Permite la separación de un programa en módulos que admiten compilación independiente. Es un lenguaje de alto nivel.
Ejemplos
A continuación se cita un programa de ejemplo Hola mundo escrito en C++:
#include <iostream>
int main() { std::cout << "Hola mundo!" << std::endl; return 0; }
Al usar la directiva #include se le dice al compilador que busque e interprete todos los elementos definidos en el archivo que acompaña la directiva (en este caso, iostream). Para evitar sobrescribir los elementos ya definidos al ponerles igual nombre, se crearon los espacios de nombres o namespace del singular en inglés. En este caso hay un espacio de nombres llamado std, que es donde se incluyen las definiciones de todas las funciones y clases que conforman la biblioteca estándar de C++. Al incluir la sentencia using namespace std le estamos diciendo al compilador que usaremos el espacio de nombres std por lo que no tendremos que incluirlo cuando usemos elementos de este espacio de nombres, como pueden ser los objetos cout y cin, que representan el flujo de salida estándar (típicamente la pantalla o una ventana de texto) y el flujo de entrada estándar (típicamente el teclado).
La definición de funciones es igual que en C, salvo por la distinción de que si main no va a recoger argumentos, basta con no ponerlos, a diferencia de C, donde, por seguridad, hay que explicitarlo usando la palabra clave void (int main(void)). El símbolo << se conoce como operador de inserción, y en este caso, está enviando a cout el texto Hola mundo! para que lo imprima en consola. El mismo operador << se puede usar varias veces en la misma expresión para concatenar la función endlstd::endl es una función plantilla (function template) que imprime un retorno de línea y vacía el buffer del flujo. al final, cuyo resultado será imprimir un retorno de línea. El operador += se utiliza para sumar el valor de la expresión a la variable a la que se le aplica. En este caso específico del código proporcionado, la línea «inverso += (contraseña % 10) * 100;» está sumando al valor actual de la variable «inverso» el resultado de multiplicar el último dígito de la variable «contraseña» por 100. Esto se repite para los otros dígitos de la contraseña para construir el número invertido.
Tipos de datos
C++ tiene los siguientes tipos fundamentales: Caracteres: char (también es un entero), wchar_t Enteros: short, int, long, long long Números en coma flotante: float, double, long double Booleanos: bool Vacío: void
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 diferentes tamaños en memoria. La lista a continuación 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 bitschar 8short 16int 32float 32double 64
Otras arquitecturas pueden requerir distintos tamaños de 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 tipos; más bien, ofrece solamente las siguientes «garantías de tipos»:
De acuerdo al estándar C99, un tipo char debe ocupar exactamente un byte compuesto de un mínimo de 8 bits independientemente de la arquitectura de la máquina. El tamaño reconocido de char es de 1. Es decir, sizeof(char) siempre devuelve 1. Un tipo short tiene al menos el mismo tamaño que un tipo char. Un tipo long tiene al menos el doble tamaño en bytes que un tipo short. Un tipo int tiene un tamaño entre el de short y el de long, ambos incluidos, preferentemente el tamaño de un apuntador de memoria de la máquina. Su valor máximo es 2147483647, usando 32 bits. Un tipo unsigned tiene el mismo tamaño que su versión signed.
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
Cabe resaltar que en C se define wchar_t como:
typedef unsigned short wchar_t;
Mientras que en C++ es en sí mismo un tipo de dato.
La palabra reservada «void»
La palabra reservada void define en C++ el concepto de no existencia o no atribución de un tipo en una variable o declaración. Es decir, una función declarada como void no devolverá ningún valor. Esta palabra reservada también puede usarse para indicar que una función no recibe parámetros, como en la siguiente declaración:
int funcion (void); Aunque la tendencia actual es la de no colocar la palabra «void».
Además se utiliza para determinar que una función no retorna un valor, como en: void funcion (int parametro);
Cabe destacar que void no es un tipo. Una función como la declarada anteriormente no puede retornar un valor por medio de return: la palabra clave va sola. No es posible una declaración del tipo: void t; //Está mal
En este sentido, void se comporta de forma ligeramente diferente a como lo hace en C, especialmente en cuanto a su significado en declaraciones y prototipos de funciones.
Sin embargo, la forma especial void * indica que el tipo de datos es un puntero. Por ejemplo:
void *memoria;
Indica que memoria es un puntero a alguna parte, donde se guarda información de algún tipo. El programador es responsable de definir estos «algún», eliminando toda ambigüedad. Una ventaja de la declaración «void *» es que puede representar a la vez varios tipos de datos, dependiendo de la operación de cast escogida. La memoria que hemos apuntado en alguna parte, en el ejemplo anterior, bien podría almacenar un entero, un flotante, una cadena de texto o un programa, o combinaciones de estos. Es responsabilidad del programador recordar qué tipo de datos hay y garantizar el acceso adecuado.
La palabra «NULL»
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».
Tenemos entonces que:
void* puntero = NULL; int entero = NULL; bool boleana = NULL; char caracter = NULL;
El valor de las variables anteriores nos daría 0. A diferencia de la variable «caracter», que nos daría el equivalente a NULL, «\0», para caracteres.
Para evitar ambigüedad en funciones sobrecargadas, puede emplearse la palabra clave nullptr. Esta palabra clave siempre representa un puntero. Por ejemplo:
void f(int a); void f(foo *a);
int main(int argc, char** argv) { f(NULL); // Se ejecuta f(int a) f(nullptr); // Se ejecuta f(foo *a) return 0; }
Principios
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)
Aunque no es estándar algunas implementaciones permiten int main(int argc, char** argv, char** env)
La primera es la forma por omisión de un programa que no recibe parámetros ni argumentos. La segunda forma tiene dos parámetros: argc, un número que describe el número de argumentos del programa (incluyendo el nombre del programa mismo), y argv, un puntero a un array de punteros, de argc elementos, donde el elemento argv[i] representa el i-ésimo argumento entregado al programa. En el tercer caso se añade la posibilidad de poder acceder a las variables de entorno de ejecución de la misma forma que se accede a los argumentos del programa, pero reflejados sobre la variable env.
El tipo de retorno de main es un valor entero int. Al finalizar la función main, debe incluirse el valor de retorno (por ejemplo, return 0;, aunque el estándar prevé solamente dos posibles valores de retorno: EXIT_SUCCESS y EXIT_FAILURE, definidas en el archivo cstdlib), o salir por medio de la función exit. Alternativamente puede dejarse en blanco, en cuyo caso el compilador es responsable de agregar la salida adecuada.
El concepto de clase
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:
Identidad, que lo diferencia de otros objetos (Nombre que llevará la clase a la que pertenece dicho objeto). Métodos o funciones miembro. Atributos o variables miembro.
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.
Este es otro ejemplo de una 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
Son unos métodos especiales que se ejecutan automáticamente al crear un objeto de la clase. En su declaración no se especifica el tipo de dato que devuelven, y poseen el mismo nombre que la clase a la que pertenecen. Al igual que otros métodos, puede haber varios constructores sobrecargados, aunque no pueden existir constructores virtuales.
Como característica especial a la hora de implementar un constructor, justo después de la declaración de los parámetros, se encuentra lo que se llama «lista de inicializadores». Su objetivo es llamar a los constructores de los atributos que conforman el objeto a construir.
Cabe destacar que no es necesario declarar un constructor al igual que un destructor, pues el compilador lo puede hacer, aunque no es la mejor forma de programar.
Tomando el ejemplo de la Clase Punto, si deseamos que cada vez que se cree un objeto de esta