490 likes | 735 Views
El lenguaje C++. A partir del lenguaje C Entorno de programación Visual C++. El entorno de programación. Solución Proyecto Hola mundo Compilar Build Link Debug. asm inline public virtual catch new template class. operator this delete private throw friend protected
E N D
El lenguaje C++ A partir del lenguaje C Entorno de programación Visual C++
El entorno de programación • Solución • Proyecto • Hola mundo • Compilar • Build • Link • Debug
asm inline public virtual catch new template class operator this delete private throw friend protected try Nuevas palabras reservadas
Nueva forma para E/S • Cualquier compilador de C++, acepta C. • La biblioteca iostream incluye los operadores cin y cout (#include <iostream>). • Ejemplo: char nombre; int num=2; std :: cout << "Introduzca el nombre del archivo " << num << ": "; std :: cin >> nombre;
Declaración de variables • En cualquier lugar del bloque: for (double suma = 0.0, int i = 0; i<n; i++) suma += a[i] • Variables const para tamaño de vectores: int main(){ const int SIZE = 5; char cs[SIZE] ; }
Punteros const • Apuntan siempre a la misma dirección. • El valor de la variable apuntada se puede modificar. • Se declaran así: char* const nombre2 = "Ramón"; • Un puntero a variable const no puede modificar el valor de esa variable.
Punteros a variables const • Se declaran así: const char*nombre1= "Ramón"; • El código: #include <stdio.h> int main(){ const int i = 2; int *p; p = &i; *p = 3; printf("i = %d", i); } En ANSI C produce i = 3, pero en C++ no compila.
Conversiones explícitas de tipo • Ejemplo de cast: (C y C++) return (int) (x/y); • C++ dispone de otra conversión: y = double(25); return int(x/y);
Sobrecarga de funciones • Funciones distintas con mismo nombre. • Distinto tipo y/o número de argumentos. • No pueden diferir sólo en el tipo de retorno. • Tampoco en que un argumento se pase por valor en una función y por referencia en la otra.
Parámetros con valores por defecto • En C++ se pueden definir valores por defecto para todos o algunos argumentos formales. • En la llamada, si no están los argumentos correspondientes, se toma el valor asignado. • Los argumentos con valores por defecto deben estar al final de la lista.
Parámetros con valores por defecto • Si se omite un argumento en la llamada, se deben omitir los siguientes en la lista. • Ejemplo: double modulo(double x[], int n=3); • En C++ se puede invocar así: v = modulo(x, n); v = modulo(x);
Variables de tipo referencia • Se declaran con el operador '&'. • Deben ser inicializadas. • Nombre alternativo para un objeto. • Utilidades más importantes: • especificación de argumentos. • especificación de tipos de retorno. • sobrecarga de operadores.
Variables de tipo referencia int i = 1; int& r = i; // r e i ahora se refieren al // mismo int int x = r; // x = 1 r = 2; // i = 2 r++; // i se incrementa a 3 • Ningún operador opera sobre una referencia. • El valor de una referencia no se puede modificar (siempre se referirá al mismo objeto). • &r es un apuntador al objeto denotado.
Los operadores new y delete • Hasta ahora variables estáticas o automáticas. • Con new y delete se crean y destruyen variables según la necesidad del programador. • Una variable puede traspasar su bloque. • Se puede crear cualquier tipo de variable con new y éste retorna un puntero de ese tipo. • No se necesita conversión de tipo.
Clases, objetos y métodos • Las clases se pueden ver como una generalización de las estructuras. • Son verdaderos tipos de datos definidos por el usuario. • Los objetos son las variables de una determinada clase. • Los métodos pueden ser funciones u operadores.
Estructura de un programa • En los archivos de cabecera (.h), por lo general, se declara la clase, con los prototipos de las funciones. • En un archivo NombreClase.cpp de implementan los constructores, funciones y operadores. • En un archivo main.cpp se define la función main.
Ejemplo: complejo.h • Se declaran los campos miembro privados: class Complejo { private: double real; double imag; • Los usuarios de la clase no podrán acceder con los operadores '.' y '->'. • Las funciones miembro sí tienen acceso.
Ejemplo: complejo.h • Se declaran un conjunto de funciones y operadores miembro en la sección pública. • Las tres primeras son los constructores: public: // Constructores Complejo(); Complejo(double, double im=0.0); Complejo(const Complejo&);
Ejemplo: complejo.h • El siguiente grupo de funciones permite dar valor a los campos: void setData(); void setReal(double); • O acceder a ellos: double getReal(){return real;} double getImag(){return imag;}
Ejemplo: complejo.h • A continuación se declara la sobrecarga de los operadores aritméticos, comparación y asignación (operadores miembro). Complejo operator+ (const Complejo&); • Y luego la sobrecarga del operador de inserción en el flujo de salida (operador amigo) friend ostream& operator<< (ostream& const Complejo&);
Sobrecarga de operadores // operador miembro + sobrecargado Complejo Complejo::operator+ (const Complejo &a) { Complejo suma; suma.real = real + a.real; suma.imag = imag + a.imag; return suma; }
Sobrecarga de operadores • Los operadores y funciones miembro se indican con el operador de resolución de alcance '::' (no así los amigos). • En una sentenciax + y; // x, y complejos se utiliza el operador sobrecargado. • x es el argumento implícito. • y se pasa explícitamente (como argumento formal a) .
Puntero this • La sobrecarga de '=' retorna (*this) que representa al argumento implícito. • Es una variable predefinida para todas las funciones (u operadores) miembro. • Contiene la dirección del objeto correspondiente. • Forma de referirse al objeto como tal (argumento implícito).
Constructores • Se debe dar valor inicial a las variables miembro. Esto se hace a través de constructores. • Se invocan automáticamente al crear un objeto de una clase. • Permiten la encapsulación. • Tienen el mismo nombre que la clase. • No tienen valor de retorno (ni siquiera void).
Inicializadores • Los constructores inicializan variables. • C++ permite inicializar variables fuera del cuerpo de una función. C_Cuenta::C_Cuenta(double unSaldo, double unInteres): Saldo(unSaldo), Interes(unInteres) // inicializadores { } // En este caso el cuerpo del constructor está vacío • Permiten definir variables miembro const.
Constructor por defecto • Es un constructor que no necesita que se le pasen argumentos para inicializar las variables. Hay dos opciones: • No tiene argumentos. • Tiene argumentos, pero todos ellos tienen asignado un valor por defecto en la declaración. • Es necesario para declaraciones de la forma Complejo z; y Complejo datos[100];
Constructor de oficio • Lo crea el compilador de C++ si el programador no define ningún constructor. • No tiene argumentos, es un constructor por defecto (no siempre un constructor por defecto es un constructor de oficio). • Suelen ser cómodos, correctos y suficientes.
Constructor de copia • Se utiliza cuando se debe crear un objeto a partir otro objeto de la misma clase. • Tiene un único argumento que es una referencia constante a un objeto de la clase. • El compilador también define un constructor de copia de oficio si el programador no lo hace (no funciona correctamente con punteros).
z2 = z1; Se supone que c1 y c2 existían previamente. Se utiliza el operador de asignación que funciona como un constructor de copia. Se debe sobrecargar '='. Constructores y operador de asignación (=). Complejo z2 = z1; • Se invoca al constructor de copia. • El constructor de copia por defecto es una copia bita bit. • Se debe sobrecargar.
Destructores • Es llamado cuando el objeto va a dejar de existir. • Para un objeto localo automático definido en un bloque, el destructor es invocado cuando el programa llega al final del bloque. • Los objetos creados con newdeben ser explícitamente destruidos.
Clases y funciones friend • Las funciones miembro (que acceden a las variables miembro) sólo pueden ser miembro de una única clase. • Una función friend de una clase es una función que no pertenece a la clase, pero que tiene permiso para acceder a sus funciones y variables miembro. • Una clase friend de otra tiene todas sus funciones amigas de esa segunda clase.
Herencia class ClaseDerivada: public o private ClaseBase • Un nombre redefinido oculta el nombre heredado. • Hay algunos elementos de la clase base que no pueden ser heredados: • Constructores • Destructores • Funciones friend • Funciones y datos estáticos de la clase • Operador de asignación (=) sobrecargado
Constructores de clases derivadas • Debe llamar al constructor de la clase base. • Se debe especificar un inicializador base. • Se puede omitir si la clase base cuenta con un constructor por defecto. C_CuentaJoven(const char *unNombre, int laEdad, double unSaldo=0.0,double unInteres=0.0): C_Cuenta(unNombre, unSaldo, unInteres)
Herencia múltiple • Una clase puede heredar de una (herencia simple) o más clases base (herencia múltiple). class CuentaEmpresarial: public Cuenta, public Empresa
PolimorfismoFunciones Virtuales • Son funciones distintas con el mismo nombre, declaradas virtual en la clase base (ligadura dinámica). • Funciones convencionales se invocan de acuerdo al tipo del objeto (en tiempo de compilación). • Con funciones virtuales se resuelve en tiempo de ejecución el problema de la asignación.
Funciones virtuales class A { public: virtual void mostrar(); } class B: public A { public: void mostrar(); } A objA; B objB; A* ptrA1; A* ptrA2; ptrA1 = &objA; ptrA2 = &objB; ptrA2->mostrar();
Funciones virtuales puras • La función virtual de la clase base debe declararse a pesar de no ser utilizada. • En este caso no es necesario definirla. • Se declara como función virtual pura: virtual funcion1() const = 0; • No se pueden definir objetos de esa clase. • Se pueden definir punteros a esa clase.
Clases abstractas • Contienen una o más funciones virtuales puras. • Si una clase derivada no define una función virtual pura, la hereda como pura y por lo tanto también es abstracta. • Una clase que define todas las funciones virtuales es una clase concreta.
Entrada/Salida • Stream o flujo: dispositivo que produce o consume información. • Flujos estándares: • cin: entrada estándar (teclado). • cout: salida estándar (pantalla). • cerr: salida de mensajes de error (pantalla). • Las clases istream, ostream e iostream son clases que heredan de ios.
Manipuladores • Variables y/o métodos miembro que controlan el formato. • Pueden tener argumentos (iomanip) o no (iostream). • Sólo afectan al flujo al que se aplican. • No guardan la configuración anterior (como sí lo hacen los indicadores).
Manipuladores • Ejemplos: • endl: se imprime un ‘\n’y se vacía el buffer de salida. • flush: se vacía el buffer de salida. • setw(int w): establece la anchura mínima de campo. cout << hex << 100; cout << setw(10) << mat[i][j] << endl; • El efecto permanece hasta que se cambia por otro manipulador.
E/S de archivos • En la biblioteca fstream se definen las clases ifstream, ofstream y fstream, que derivan de istream y ostream y a su vez de la clase ios. • Ejemplos: fstream archivo; archivo.open("datos.dat", ios::in); ifstream archivo("datos.dat");
Excepciones • Parte del código puede no ejecutarse por algún error inesperado. • Si ocurre una excepción se interrumpe la normal ejecución del código. • Se pueden manejar realizando una acción adecuada para dejar al sistema en un estado estable.
Excepciones en C++ • Se separa el código para el caso en que ocurre una situación excepcional y el que no: • try: identifica un bloque de código en el cual puede surgir una excepción. • throw: causa que se origine una excepción. • catch: identifica el bloque de código en el cual la excepción se maneja.
Excepciones en C++ int main(void){ int counts[] = {34, 54, 0, 27, 0, 10, 0}; int time = 60; // One hour in minutes for(int i = 0 ; i < sizeof counts /sizeof counts[0] ; i++) try{ cout << endl<< "Hour " << i+1; if(counts[i] == 0) throw "Zero count - calculation not possible."; cout << " minutes per item: " << static_cast<double>(time)/counts[i]; }catch(const char aMessage[]){ cout << endl<< aMessage<< endl; } return 0; }
Excepciones en C++ • Cuando la excepción es lanzada (throw) la secuencia de ejecución continúa con el bloque catch. • Después de ejecutarse el código del bloque catch la ejecución continúa con la siguiente iteración del for. • El compilador considera los bloques try y catch como una única unidad.