martes, 10 de enero de 2017

Capítulo 6

Capítulo 6. Parametros, ambito, sobrecarga El camnio de c++ es largo, pero se sigue avanzando. Veamos las funciones inline, un recurso interesante para mejorar el rendimiento. /** * Inline.cpp * Programa para probar funciones Inline * Las funciones Inline no se compilan como funciones aparte, * lo que se hace al compilar es añadir el contenido de la funcion haya * donde se se invoca. Con lo que es mucho mas rapido de ejecutar * y ademas nos da la limpieza de separar el codigo. * * Pello Xabier Altadill Izura * * Compilado: g++ Inline.cpp -o Inline */ using namespace std; #include // las funciones en CPP las debemos declarar antes de invocar // aqui tenemos el prototipo. Si no se pone tendremos ERROR de compilador // Declaramos la funcion como inline inline double Calcula (double a, double b); // Log : saca un mensaje por pantalla void Log(char *mensaje); // Variables globales long variable = 666; char *PROGRAMA = "Globales> "; int main () { // Sacamos por salida standar un mensaje Log("Vamos a probar los operadores"); unsigned int test = 0; double a = 23, b = 21, c = 34; // Tomamos el valor a Log("Dame valores. \na="); cin >> a; // Tomamos el valor b cout << "b="; cin >> b; cout << "Y ahora son estos: b=" << b << " a=" << a << " global:" << variable << "Y el resultado de la funcion c=" << c << endl; // Probamos la funcion Log("Venga va vamos"); return 0; } /** * Calcula * parametros: double a, double b * devuelve double * En la implementacion no hace falta volver a poner INLINE */ 19 Capítulo 6. Parametros, ambito, sobrecarga double Calcula (double a, double b) { a *= 35462; b *=32546 + a; return (a / b) * variable; } /** * Log * parametros: char *mensaje * devuelve void */ void Log (char *mensaje) { cout << PROGRAMA << mensaje << endl; } Paso de parametros Vamos a ver formas de pasar parametros. /** * Parametros.cpp * Programa para probar los parametros de las funciones y * la forma de aplicar valores por defecto * * Pello Xabier Altadill Izura * * Compilado: g++ Parametros.cpp -o Parametros */ using namespace std; #include // las funciones en CPP las debemos declarar antes de invocar // aqui tenemos el prototipo. Si no se pone tendremos ERROR de compilador double Calcula (double a, double b); // Log : saca un mensaje por pantalla void Log(char *mensaje = "Sin valor prefijado"); // suma: suma dos valores int Suma(int a = 0, int b = 0, int c = 0); // Variables globales long variable = 666; char *PROGRAMA = "Globales> "; int main () { // Sacamos por salida standar un mensaje Log("Vamos a probar los operadores"); // Llamada sin parametros Log(); unsigned int test = 0; int a = 23, b = 21, c = 34, d = 0; // Llamanda sin parametros d = Suma(); cout << "Y el resultado de la funcion Suma sin parametros :" << d << endl; // Llamada con parametros 20 Capítulo 6. Parametros, ambito, sobrecarga d = Suma(a,b,c); cout << "Y el resultado de la funcion Suma :" << d << endl; // Probamos la funcion Log("Venga va vamos"); return 0; } /** * Calcula * parametros: double a, double b * devuelve: double */ double Calcula (double a, double b) { return (a / b) * variable; } /** * Log * parametros: char *mensaje * devuelve: void * NOTA: no hace falta volver a poner el valor prefijado */ void Log (char *mensaje) { cout << PROGRAMA << mensaje << endl; } /** * Suma * parametros: int a, int b, int c * devuelve: int */ int Suma (int a = 0, int b = 0, int c = 0) { Log("Vamos a ver. Estamos en suma. "); // Devolvemos un valor return (a + b + c); } Sobrecarga de funciones La sobrecarga es otro concepto básico en la POO. Aqui se muestra un boton. /** * Sobrecarga.cpp * Programa para probar la sobrecarga de funciones * La sobrecarga es una misma funcion con distintos parametros * Con la sobrecarga logramos el POLIMORFISMO de clases y funciones * * Pello Xabier Altadill Izura * * Compilado: g++ Sobrecarga.cpp -o Sobrecarga */ using namespace std; #include // las funciones en CPP las debemos declarar antes de invocar 21 Capítulo 6. Parametros, ambito, sobrecarga // aqui tenemos el prototipo. Si no se pone tendremos ERROR de compilador double Calcula (double a, double b); int Calcula (int a, int b); float Calcula (float a, float b); // Log : saca un mensaje por pantalla // Esto provocaria error de compilador por ambiguedad de sobrecarga //void Log(); // Log : saca un mensaje por pantalla // NOTA: el valor por defecto solo se pone en la DECLARACION void Log(char *mensaje = "Sin valor prefijado"); // suma: suma dos valores int Suma(int a = 0, int b = 0, int c = 0); // Variables globales long variable = 666; char *PROGRAMA = "Globales> "; int main () { // Sacamos por salida standar un mensaje Log("Vamos a probar los operadores"); // Llamada sin parametros Log(); unsigned int test = 0; int a = 23, b = 21, c = 34, d = 0; // Llamanda sin parametros d = Suma(); cout << "Y el resultado de la funcion Suma sin parametros :" << d << endl; // Llamada con parametros d = Suma(a,b,c); cout << "Y el resultado de la funcion Suma :" << d << endl; // Probamos la funcion Log("Venga va vamos"); return 0; } /** * Calcula * parametros: double a, double b * devuelve: double */ double Calcula (double a, double b) { return (a / b) * variable; } /** * Calcula * parametros: float a, float b 22 Capítulo 6. Parametros, ambito, sobrecarga * devuelve: float */ float Calcula (float a, float b) { return (a / b) * variable; } /** * Calcula * parametros: long a, long b * devuelve: long */ long Calcula (long a, long b) { return (a / b) * variable; } /** * Log * parametros: char *mensaje * devuelve: void */ void Log (char *mensaje) { cout << PROGRAMA << mensaje << endl; } /** * Suma * parametros: int a, int b, int c * devuelve: int */ int Suma (int a = 0, int b = 0, int c = 0) { Log("Vamos a ver. Estamos en suma. "); // Devolvemos un valor return (a + b + c); } El ambito Hasta donde se identifica una variable? Para saltarnos todas las vallas podemos usar variables globales. No conviene abusar de este tipo de variables. /** * Globales.cpp * Programa para probar variables y su scope * * Pello Xabier Altadill Izura * * Compilado: g++ Globales.cpp -o Globales */ using namespace std; #include // las funciones en CPP las debemos declarar antes de invocar // aqui tenemos el prototipo. Si no se pone tendremos ERROR de compilador double Calcula (double a, double b); 23 Capítulo 6. Parametros, ambito, sobrecarga // Log : saca un mensaje por pantalla void Log(char *mensaje); // Variables globales long variable = 666; char *PROGRAMA = "Globales> "; int main () { // Sacamos por salida standar un mensaje Log("Vamos a probar los operadores"); unsigned int test = 0; double a = 23, b = 21, c = 34; // Tomamos el valor a Log("Dame valores. \na="); cin >> a; // Tomamos el valor b cout << "b="; cin >> b; cout << "Y ahora son estos: b=" << b << " a=" << a << " global:" << variable <<< "Y el resultado de la funcion c=" << c << endl; // Probamos la funcion Log("Venga va vamos"); return 0; } /** * Calcula * parametros: double a, double b * devuelve double */ double Calcula (double a, double b) { return (a / b) * variable; } /** * Log * parametros: char *mensaje * devuelve void */ void Log (char *mensaje) { cout << PROGRAMA << mensaje << endl; } 24 Capítulo 7. Clases Tu primera clase c++ No hay que perder de vista el hecho de que c++ es un lenguaje orientado a objetos. Sin animos de volver a explicar que es la POO, los beneficios que constituye vamos a limitarnos a resumir. Una clase c++ es la representacion de un objeto. Un objeto es una entidad formada por sus atributos y sus metodos. Con el afan de hacer las cosas ordenadamente, siempre se separa la definicion de la clase en un fichero de cabedeceras (extension .hpp, similar al .h de lenguaje c) y la implementacion se especifica en un fichero cpp. Generalmente las clases c++ tienen el mismo aspecto: se definen unos atributos y unos metodos. Entre los metodos se pueden incluir metodos constructores y la destructora. Ademas de eso se puede definir si los atributos y clases son publicas, protegidas y privadas, dependiendo del nivel de encapsulacion que le queramos dar a la clase. Veamos la representacion del objeto coche en una clase c++: /** * Coche.hpp * Clase cabecera que define el objeto Coche * * Pello Xabier Altadill Izura * * No se compila. */ using namespace std; #include class Coche { public: Coche(); Coche(char *m,int cil,int cab); ~Coche(); void arranca(); void detiene(); void acelera(); private: char *marca; int cilindrada; int caballos; }; Y este seria el fichero de implementacion (se puede tener todo en un unico fichero) /** * Coche.cpp * Fichero que implementa la cabecera de la clase Coche. * NO HACE NADA CONCRETO solo es una muestra * * Pello Xabier Altadill Izura * 25 Capítulo 7. Clases * Compilar usando: g++ -c Coche.cpp */ // Hay que incluir el fichero de cabecera #include "Coche.hpp" // Implementacion de constructor Coche::Coche() { cout << "Coche creado." << endl; } // Implementacion de constructor (con SOBRECARGA) Coche::Coche (char *m,int cil,int cab) {} // Implementacion de destructor. Util para liberar memoria. Coche::~Coche() { cout << "Coche destruido." << endl; } // implementaciones de metodos... void Coche::arranca() {} void Coche::detiene() {} void Coche::acelera() {} /** * Podemos usar una clase main para hacer testeos con la clase * NOTA IMPORTANTE * Atencion : al usar esta clase en otra que ya tiene funcion * main, no se puede tener otra main. */ //int main () { //cout << "Lo hise!!\n" << endl; //return 1; //} Podemos usar clases dentro de otras clases? si claro. Veamos la definicion de un Garaje. /** * Garaje.hpp * Cabecera del objeto Garaje * * En este caso invocamos otro objeto: Coche * * Pello Xabier Altadill Izura * * La cabecera como tal no se compila */ using namespace std; #include #include "Coche.hpp" /* * Definicion de clase Garaje 26 Capítulo 7. Clases */ class Garaje { private: int maxCoches; public: Garaje(); Garaje(int maxCoches); ~Garaje(); int entra(Coche coche); int sale(Coche coche); bool estaLleno(); }; Y esta seria la implementacion: /** * Garaje.cpp * Implementacion de Clase Garaje * * Pello Xabier Altadill Izura * Atencion: necesitamos el archivo objeto de la clase Coche!!! * Compilar con: g++ -c Coche.cpp * g++ -Wall Garaje.cpp Coche.o -o Garaje */ #include "Garaje.hpp" /* * Implementacion de clase Garaje */ /** * Constructor por defecto */ Garaje::Garaje(){ cout << "Garaje." << endl; maxCoches = 3; } /** * Constructor parametrizado */ Garaje::Garaje(int mx){ maxCoches = mx; } /** 27 Capítulo 7. Clases * Destructor */ Garaje::~Garaje(){} /** * entra: un coche entra en el garaje */ int Garaje::entra(Coche coche) { cout << " Entra un coche." << endl; return 0; } /** * sale: un objeto coche sale del garaje */ int Garaje::sale(Coche coche) { cout << " Sale un coche." << endl; return 0; } /** * estaLleno?: devuelve booleano con la respuesta */ bool Garaje::estaLleno() { return false; } /** * y aqui la funcion main para hacer nuestras pruebillas */ int main () { cout << " Creamos un garaje. " << endl; Garaje garaje = Garaje(); // Creamos un par de Coches Coche cocheAzul = Coche(); Coche cocheRojo = Coche(); // Metemos y sacamos los coches garaje.entra(cocheAzul); garaje.entra(cocheRojo); garaje.sale(cocheRojo); } Funciones o metodos Setter/Getter Por mania o por costumbre o porque asi lo establecen los puristas mas talibanes de la POO casi nunca se deja acceder directamente a los atributos de una clase (se definen como private) y para acceder a ellos se implementan funciones set/get. Las herramientas de desarrollo suelen incluir la opcion de generar ese codigo de forma automatizada. 28 Capítulo 7. Clases Figura: nunca tomes a broma a un desarrollador OO Sin la menor intencion de alimentar la ya tradicional Yihad entre desarrolladores, mostremos un ejemplo y digamos de paso que no esta demas definir estas funciones como inline; cumplimos como profesionales pero no perdemos eficacia. El objeto PERRO /** * Perro.hpp * Cabecera de la clase Perro con sus funciones get/set para el atributo edad * * Pello Xabier Altadill Izura * */ using namespace std; #include class Perro { public: Perro (int initialAge); ~Perro(); int GetAge() { return itsAge;} // inline? void SetAge (int age) { itsAge = age;} // inline? void Ladra() { cout << "Guau Guau arrr...\n";} // inline? private: int itsAge; }; Y su implementacion /** * Perro.cpp * Clase que implementa la clase Perro * 29 Capítulo 7. Clases * Pello Xabier Altadill Izura * * Compilado: g++ Perro.cpp -o Perro */ #include "Perro.hpp" Perro::Perro(int initialAge) //constructor { itsAge = initialAge; } Perro::~Perro() //destructor { cout << " objeto destruido." << endl; } /** * La funcion principal, crea un perro y le hace ladrar */ int main() { bool test = false; Perro Canelo(5); Canelo.Ladra(); cout << "Canelo es un perro cuya edad es: " ; cout << Canelo.GetAge() << " años\n"; Canelo.Ladra(); Canelo.SetAge(7); cout << "Ahora Canelo es " ; cout << Canelo.GetAge() << " años\n"; return 0; }

No hay comentarios:

Publicar un comentario