martes, 10 de enero de 2017

Capítulo 12. Arrays

Arrays Se dice arrays o arreglos? en fin. En c++ podemos definir y usar los arrays casi como en C. Ademas tenemos la ventaja de poder crear arrays de objetos. Veamos un programa en c++ que juega con los arrays: /** * ArrayEjemplo.cpp * Clase que inicializa y maneja algunos arrays * * Pello Xabier Altadill Izura * * Compilado: g++ ArrayEjemplo.cpp -o ArrayEjemplo */ using namespace std; #include // Funcion principal int main () { // Declaramos dos arrays de enteros de 15 elementos [0..14] int arreglo1[15], arreglo2[15]; int i; // Iniciamos todos los componentes con el valor 0 // ahorramos tiempo con una asignacion multiple for ( i = 0 ; i < 15 ; i++ ) { // recorremos de 0 a 14 arreglo1[i] = arreglo2[i] = 0; } // Declaramos mas arrays y los iniciamos: long arrayLongs[5] = { 77, 33, 15, 23, 101 }; // Lo recorremos y vemos sus componentes por pantalla // Atencion!! esto nos recorreria mas de lo necesario //for ( i = 0 ; i < sizeof(arrayLongs) ; i++ ) { // para sacar el valor real: int tamano_real = sizeof(arrayLongs)/sizeof(arrayLongs[0]); for ( i = 0 ; i < tamano_real ; i++ ) { cout << "valor de componente " << i << ": " << arrayLongs[i] << endl; } // Lo mismo, pero nos es necesario poner el tamaño si ya lo especificamos // al iniciar el array char arrayChars[] = { ’A’, ’s’, ’i’, ’m’, ’o’, ’v’}; // nota: un array de chars = es un string char nombre[] = "Isaac"; cout << "Mostrando array de caracteres." << endl; tamano_real = sizeof(arrayChars)/sizeof(arrayChars[0]); for ( i = 0 ; i < tamano_real ; i++ ) { cout << "valor de componente " << i << ": " << arrayChars[i] << endl; 59 Capítulo 12. Arrays } // Enumeraciones: podemos combinarlas con arrays enum Dias {Ene, Feb, Mar, Abr, May, Jun, Jul, Ago, Sep, Oct, Nov, Dic, LosMeses}; // A cada enumeracion le corresponde un numero, si no se especifica, // la numeracion ira incremental Ene=0, Feb=1, Mar=2,..,LosMeses=12 //Podemos declarar el siguiente array, donde LosMeses nos da la longitud 12 int diasLibres[LosMeses] = {2, 4, 6, 2, 5, 4, 10, 15, 10, 3, 4, 10}; Dias tmpDia; for (i = 0; i < LosMeses; i++) { tmpDia = Dias(i); cout << "Dias libres "<< tmpDia << " =" << diasLibres[i] << endl; } // The Matrix!!! vamos a definir arrays multidimensionales: int theMatrix[5][3] = { {3,6,8}, {9,9,9}, {0,1,0}, {6,6,6}, {3,1,1}}; // Para recorrerlo ponemos un for doble int j; for (i = 0; i<5 ; i++) { for (j = 0; j< 3; j++) { cout << " matrix[" << i << "][" << j <<"] = " << theMatrix[i][j] << endl; } } return 0; } Arrays de objetos Vamos a ver un ejemplo de arrays de objetos. Se crea el objeto Robot y con el se formara un ejercito de robots. /** * Robot.hpp * Clase que define el objeto Robot * * Pello Xabier Altadill Izura * */ class Robot { private: char *nombre; public: Robot(char *nombre = "Nestor-5") { this->nombre = nombre; } ~Robot(); Robot(const Robot &); 60 Capítulo 12. Arrays char *getNombre() const { return nombre;} void hablar(char *texto); void evolucionar(); void matar(Robot victima); }; Esta es la implementacion. /** * Robot.cpp * Fichero que implementa la clase Robot. Vamos a crear un array de robots * * Pello Xabier Altadill Izura * */ using namespace std; #include #include "Robot.hpp" // Destructor Robot::~Robot() {} // Constructor copia Robot::Robot(const Robot & robotOrigen) { nombre = new char; nombre = robotOrigen.getNombre(); cout << "Copia creada! Bzzzz. Me llamo: "<< nombre <hablar("Jeje, todavia existo yo."); // Metemos dos nuevos robots en el array robobsoletos[5] = rarito; rarito = new Robot("Sheldon"); robobsoletos[6] = rarito; // hacemos una llamada desde el componente del array de punteros robobsoletos[6]->matar(ejercitoDelMal[12]); return 0; } 62 Capítulo 13. Herencia La herencia Como bien se sabe la herencia no se reparte: se descuartiza. Bromas aparte, la herencia constituye una de las herramientas mas poderosas del culto OO. Si una clase hereda de la otra, lo que hereda son todos sus atributos y metodos. Ademas de heredarlos puede sobreescribirlos, tanto los constructores-destructores como los metodos convencionales. Veremos un ejemplo claro que resume lo que se puede hacer y los efectos de la herencia Por un lado vemos la clase generica vehiculo y su descendiente: el coche. La clase Vehiculo /** * Vehiculo.hpp * Clase que define el objeto vehiculo * * Pello Xabier Altadill Izura * */ using namespace std; #include enum tipo_combustible { QUEROSENO, CANNABIS, GIRASOL, GASOIL, AGUA, PLUTONIO }; class Vehiculo { protected: int cilindrada; tipo_combustible combustible; char *marca; public: Vehiculo(); Vehiculo(char *marca); Vehiculo(int cilindrada, tipo_combustible combustible, char *marca); ~Vehiculo(); Vehiculo(const Vehiculo &); void arrancar(); void mover(int metros); // metodo tipo virtual, util cuando definamos PUNTEROS Y REFERENCIAS a vehiculo virtual void claxon() const { cout << " Mec-meeec!! Que? meeec! Que de que? meec!" << endl; } char *getMarca() const {return this->marca;} tipo_combustible getCombustible() const {return this->combustible;} int getCilindrada() const {return this->cilindrada;} }; 63 Capítulo 13. Herencia Y su implementacion... /** * Vehiculo.cpp * Fichero que implementa la clase vehiculo * * Pello Xabier Altadill Izura * * Compilacion: g++ -c Vehiculo.cpp */ #include "Vehiculo.hpp" // Constructor Vehiculo::Vehiculo() { cout << " Vehiculo creado" << endl; } // Constructor Vehiculo::Vehiculo(char *marca) { this->marca = marca; cout << " Vehiculo creado con parametro marca: " << marca << endl; } // Constructor con valores iniciados Vehiculo::Vehiculo(int cilindrada, tipo_combustible combustible, char *marca) : cilindrada(cilindrada), combustible(combustible), marca(marca) { cout << " Vehiculo creado con valores: " << endl; cout << " cilindrada: " << cilindrada << endl; cout << " combustible: " << combustible << endl; cout << " marca: " << marca << endl; } // Destructor Vehiculo::~Vehiculo() { cout << " Vehiculo destruido" << endl; } // Constructor copia de vehiculo Vehiculo::Vehiculo(const Vehiculo & vehiculoOrigen) {} // Arrancamos el vehiculo void Vehiculo::arrancar() { cout << " arrancando vehiculo. Brruum!!" << endl; } 64 Capítulo 13. Herencia // Movemos el vehiculo unos metros void Vehiculo::mover(int metros) { cout << " moviendo vehiculo " << metros << " metros" << endl; } El coche, herencia de Vehiculo /** * Coche.hpp * Clase que define el objeto Coche, hijo de vehiculo, señor del capitalismo * * Pello Xabier Altadill Izura * */ #include "Vehiculo.hpp" class Coche : public Vehiculo { protected: int caballos; char *motor; public: // Atencion: constructor pasando parametros por defecto estilo guru // pero invocando a su clase padre Coche():Vehiculo("Audi") { cout << " Coche destruido invocando al constructor vehiculo" << endl; } // Constructor que sobreescribe al de vehiculo! Coche(char *marca); // Constructor Coche(int cilindrada, tipo_combustible combustible, char *marca); // Constructor Coche(int caballos, char *motor) { this->caballos = caballos; this->motor = motor; cout << " Coche construido con caballos y motor" << endl; } // Destructor ~Coche(); // Constructor copia Coche(const Coche &); // Metodo sobreescrito void arrancar(); // metodo que sobreescribe al virtual 65 Capítulo 13. Herencia void claxon() const; // getter/setter int getCaballos() const {return this->caballos;} // inline char *getMotor() const {return this->motor;} // inline }; Y su implementacion /** * Coche.cpp * Fichero que implementa la clase Coche * * Pello Xabier Altadill Izura * * Compilacion: g++ -c Vehiculo.cpp * g++ Coche.cpp Vehiculo.o -o Coche */ #include "Coche.hpp" // Constructor de coche que sobreescribe Coche::Coche(char *marca) { cout << " Coche construido con marca: " << marca << endl; } // Constructor de coche Coche::Coche(int cilindrada, tipo_combustible combustible, char *marca) { cout << " Coche construido con parametros" << endl; } // Destructor de coche Coche::~Coche() { cout << " Coche destruido" << endl; } // Constructor copia de Coche Coche::Coche(const Coche & cocheOriginal) { marca = new char; marca = cocheOriginal.getMarca(); cout << " Copia de coche" << endl; } // metodo sobreescrito void Coche::arrancar () { cout << " BOOM! pam! pam! pret pret pret... pam! pret pret" << endl; } 66 Capítulo 13. Herencia // metodo que sobreescribe al virtual void Coche::claxon() const { cout << " MOOOOOC!! Mecagon tus muelas MOC-MOOOC!!" << endl; } // Funcion principal int main () { // Creamos varios coches. Veremos que al ser objetos heredados // se invocaran los constructores, copias, y destructores de la clase // padre Vehiculo Coche mibuga = Coche(); Coche tucarro = Coche(mibuga); // probando constructor sobrescrito: se invocan los dos! Coche tequi = Coche("Alfalfa Romero"); // podemos invocar los metodos del padre y usar sus atributos cout << "La marca de mi buga es: " << mibuga.getMarca() << endl; mibuga.arrancar(); // Invocando metodo sobreescrito: solo se invoca el del coche. tucarro.arrancar(); // Y si queremos invocar el metodo del padre?? tequi.Vehiculo::arrancar(); // Creamos otro vehiculo con puntero a un COCHE Vehiculo *vehiculo = new Coche("LanborJini"); // Esto invocara el metodo de vehiculo, el de la clase PADRE vehiculo->arrancar(); vehiculo->mover(3); // Ahora queremos invocar el claxon, pero a cual de los metodos // se invocara, al del Coche o al de la clase vehiculo? al haber // definido el metodo claxon como virtual, se invocara el metodo correcto // que es el del coche (vehiculo es un puntero a coche). vehiculo->claxon(); return 0; } OUTPUT La salida de la ejecucion de Coche.cpp seria: Vehiculo creado con parametro marca: Audi Coche destruido invocando al constructor vehiculo Vehiculo creado Copia de coche Vehiculo creado Coche construido con marca: Alfalfa Romero La marca de mi buga es: Audi BOOM! pam! pam! pret pret pret... pam! pret pret BOOM! pam! pam! pret pret pret... pam! pret pret arrancando vehiculo. Brruum!! Vehiculo creado Coche construido con marca: LanborJini arrancando vehiculo. Brruum!! moviendo vehiculo 3 metros 67 Capítulo 13. Herencia MOOOOOC!! Mecagon tus muelas MOC-MOOOC!! 

No hay comentarios:

Publicar un comentario