180 likes | 352 Views
El lenguaje C++. Isidro González Caballero (Universidad de Oviedo) Técnicas de Comp. en Física Santander, 13/12/2010. 2. MiClase es el nombre de la clase. Visibilidad: public : Visible para cualquier otra clase protected : Visible solo para subclases
E N D
El lenguaje C++ Isidro González Caballero (Universidad de Oviedo) Técnicas de Comp. en Física Santander, 13/12/2010 2
MiClase es el nombre de la clase • Visibilidad: • public: Visible para cualquier otra clase • protected: Visible solo para subclases • private: Visible solo para la propia clase Datos: Definen el estado de los objetos de esta clase Clases class MiClase { public: MiClase(...); //Constructor ~MiClase(); //Destructor //Metodos int metodo1(...); //ejemplo protected: //Data members int dato1; //ejemplo float dato2; //ejemplo };
Constructor: • Puede haber varios • Puede tomar argumentos • Es la función que se ejecuta cuando se crea un objeto • Destructor: • Solo puede haber uno • No toma argumentos • Es lo último que se ejecuta cuando se destruye un objeto Métodos: Definen el comportamiento de una clase Clases class MiClase { public: MiClase(...); //Constructor ~MiClase(); //Destructor //Metodos int metodo1(...); //ejemplo protected: //Data members int dato1; //ejemplo float dato2; //ejemplo };
Objetos de una clase • Los objetos de una clase se declaran: • Como cualquier variable si hay constructor que no toma argumentos • Pasándole los parámetros del constructor a la variable como si fuera una función • Los métodos se acceden usando el operador punto (.) (o flecha, ->, para punteros) class MiClase { public: MiClase(int a=0); bool foo() {return true;} }; MiClase miobj; //== miobj(0) MiClase miobj3(3); miobj.foo(); //true
Ejemplo: Clase complejo class Complex { public: Complex(double re, double im); ~Complex(); double getRe() const; double getIm() const; double getModulo() const; … void setRe(double re); void setIm(double im); protected: //Data members double Real; //parte real double imaginario; //parte imaginaria }; Nombre de la clase Parte pública: Accesible a todo el mundo • Parte protegida: • Accesible a las subclases • Suele contener los atributos No olvidéis el punto y coma
Ejemplo: Clase complejo class Complex { public: Complex(double re, double im); ~Complex(); double getRe() const; double getIm() const; double getModulo() const; … void setRe(double re); void setIm(double im); protected: //Data members double Real; //parte real double imaginario; //parte imaginaria }; Constructor Destructor Get methods:Permiten averiguar información sobre el objeto Set methods: Permiten modificar el estado del objeto Atributo: Parte real Atributo: Parte imaginaria
Ejemplo: Clase complejo class Complex { public: Complex(double re, double im); ~Complex(); double getRe() const; double getIm() const; double getModulo() const; … void setRe(double re); void setIm(double im); protected: //Data members double Real; //parte real double imaginario; //parte imaginaria }; Const methods: Sólo pueden utilizarse con objetos constantes Para recuperar la parte imaginaria: acceso directo a los data members Para recuperar el módulo: hay que calcularlo a partir de los atributos (oculto a los usuarios de la clase) Para modificar la parte real Para modificar la parte imaginaria
Ejemplo: Clase complejo • tar xvfz complejo1.tar.gz • La clase Complex está… • …declarada en el fichero Complex.hh • … implementada en el fichero Complex.cc • Vemos como crear objetos de la clase Complex en el fichero main.cc • Usamos una función para “imprimir” los objetos de la clase Complex: void PrintComplex(const Complex&); • Compilamos con compila.csh • Argumento por referencia constante: • Nos ahorramos una copia de memoria • Nos aseguramos que la variable no se modifica
Sobrecarga de operadores • Permite redefinir cómo actúan los operadores sobre los objetos de nuestras clases • Se suelen definir dentro de la propia clase • Salvo casos específicos (operadores << y >>) • Hay que tener cuidado con cuestiones como la conmutatividad • Son funciones o métodos como cualquier otro con nombres un poco especiales • La expresión:objA + objBse transforma en:objA.operator+(objB)o se transforma en: operator+(objA, objB)
Ejemplo 2: Complex avanzado • unzip complejo2.zip • Observar: • Constructor con valores por defecto • Sobrecarga de operadores en la clase • Sobrecarga del operador << • Complex.hh contiene la declaración y Complex.cc contiene la implementación • main.cc contiene un ejemplo de utilización • No usamos ninguna función para imprimir el complejo… usamos el operador!
Ejercicios propuestos • Sobrecargar el operador / y el operador -= • Obligatorio: Sobrecargar el operardor lógico de igualdad: • Complex == Complex a==b; //Igual que lo de abajo a.operator==(b); //(a==b)->t/f • Opcional: Redefinir el operador de entrada >> • Obligatorio: Implementar una clase “vector en el plano”
Constructor: Algo más • Al construir un objeto de una clase se reserva el espacio para sus data members • Con sus valores por defecto (si los tienen) • A continuación le asignamos valores… • … luego estamos haciendo 2 asignaciones • … lo cual no es muy eficiente • Se soluciona con la siguiente notación (ejemplo Complex): Complex::Complex(double r, double i):Re(r), Im(i) {//…}
Punteros (¿qué son?) • Almacenan direcciones de memoria • Se utilizan en general para • Gestionar dinámicamente (en tiempo de ejecución en lugar de en tiempo de compilación) memoria • Arrays de dimensión variable • Pasar argumentos por referencia a los métodos (aunque no es necesario) • Inclusión de objetos por referencia. • Una misma copia de un objeto puede estar en varios objetos • Si se modifica en uno de ellos se modifica en todos. • Cadenas de caracteres • Los arrays son equivalentes a punteros
Punteros (utilización) • Se declaran con un asterisco (‘*’) después del tipo • Cuando no apuntan a ningún sitio su valor es 0 • Ojo: No es su valor por defecto. ¡Se debe inicializarlos! • Se accede al objeto al que apuntan poniendo un ‘*’ delante del nombre del puntero • Se accede a la posición de memoria de un objeto poniendo ‘&’ delante de su nombre • El acceso a los métodos del objeto apuntado por un puntero se hace con el operador ‘->’ • Cadenas de caracteres: • Son de tipo char* • Se inicializan con una cadena entre comillas • Su dimensión es el número de caracteres + 1 (\0, terminación de cadena)
Punteros (ejemplos) int *intptr; //Declaracion de un puntero int* intptr2; //Idem double pi = 3.1415; double *piptr = π //piptr apunta a pi //Las dos lineas siguientes imprimen lo mismo cout << “El valor de pi es “ << pi << endl; cout << “El valor de pi es “ << *piptr << endl; double otro = *piptr; //otro toma el valor de pi (no dir) otro = 6.28; //pi sigue valiendo lo mismo y piptr tambien piptr = &otro; //piptr ahora apunta a otro cout << “El valor de pi es “ << *piptr << endl; //6.28 int miarray[] = {1, 2, 3}; //Inicialización int uno = *miarray; //uno == 1
Gestión dinámica de memoria • Utilizamos los operadores new (para crear nuevo espacio) y delete (para liberar el espacio creado) • En general por cada new que pongamos tendremos un delete en algún sitio • Soportan la posibilidad de crear arrays • Tipo* variable = new Tipo[dimension]; • A partir de este momento se puede usar la sintaxis de arrays • delete[] variable; Muy importantes los corchetes • Si no se usan solo se libera el espacio del primer elemento
Gestión dinámica de memoria (ejemplo) Miclase* miclasePtr = 0; //Con inicialización miclasePtr = new Miclase(…) //Creamos un nuevo objeto Miclase miclasePtr->AlgunMetodo(…); //Acceso a AlgunMetodo() delete miclasePtr; //Liberamos la memoria de miclasePtr int nelems; … double nums[nelems]; //ERROR: dim desconocida al compilar double* nums = new double[nelems]; //Reservamos memoria for (unsigned int i = 0; i < nelems; i++) nums[i] = i*10; //Esto imprime ‘El cuarto elemento vale: 30’ cout << “El cuarto elemento vale: “ << nums[3] << endl; delete[] nums; //Liberando la memoria
Ejemplo: realvector • unzip realvector1.zip • Definimos una clase RealVector: • Array cuya dimensión puede decidirse en tiempo de ejecución • Reserva/borra memoria al crearse/destruirse • Acceso y modificación con el operador [ ] • Mismo operador const y no const • … correr y ver los problemas… • Borramos 2 veces lo mismo… • …operador de asignación por defecto