15. Clases & amigas c++
Clases dentro de Clases
Una clase puede ser el atributo de otra clase.
Veamos como metemos la clase soldado dentro del tanque, esta seria la cabecera:
Mediante la palabra reservada friend podemos declara relaciones de confianza entre clases y permitir que una clase amiga pueda acceder a los atributos y metodos privados de esa clase.
Veamos el ejemplo con la Pluma y la Espada. La pluma vence a la espada pero ademas la declara como amiga porque es asi de enrollada. Veamos la declaracion de Pluma:
Podemos declarar una funcion como amiga y nos dara acceso a TODO a traves de ese funcion.
Para ilustrar esto definimos las clases Chico y Chica en un unico fichero
Una clase puede ser el atributo de otra clase.
Veamos como metemos la clase soldado dentro del tanque, esta seria la cabecera:
/** * Tanque.hpp * Clase que define el objeto Tanque . El objeto tanque estara lleno * de Objeto soldados, lo que nos sirve para demostrar el uso de clases * como atributos, etc.. * * Pello Xabier Altadill Izura * */ #include <iostream.h> #include "Soldado.hpp" class Tanque { public: // constructores Tanque(); Tanque(char *nombre, int proyectiles,Soldado soldado); // destructor ~Tanque(); // copia Tanque(Tanque const &); // get/set char *getNombre () const { return this->nombre; } void setNombre (char *nombre) { this->nombre = nombre; } int getProyectiles () const { return this->proyectiles; } void setProyectiles (int proyectiles) { this->proyectiles = proyectiles; } Soldado getSoldado () const { return this->soldado; } void setSoldado (Soldado soldado) { this->soldado = soldado; } void avanzar(int metros) const; void disparar(); private: char *nombre; int proyectiles; Soldado soldado; };Y su implementacion:
/** * Tanque.cpp * Programa que implementa la clase Tanque * * Pello Xabier Altadill Izura * Compilacion: g++ Tanque.cpp -o Tanque */ #include "Tanque.hpp" // Constructor Tanque::Tanque(): nombre("Supertanque"), proyectiles(10), soldado(Soldado()) { cout << "-clase Tanque- Tanque " << nombre << " construido. Proyectiles: " << proyectiles << endl; } // Constructor parametrizado Tanque::Tanque(char *nombre, int proyectiles, Soldado soldado) { this->nombre = nombre; this->proyectiles = proyectiles; this->soldado = soldado; cout << "-clase Tanque- " << nombre << " :Tanque construido. Proyectiles: " << proyectiles << endl; } // Destructor Tanque::~Tanque() { cout << "-clase Tanque- Tanque "<< this->getNombre() << " destruido."<< endl; } // constructor copia Tanque::Tanque(const Tanque & original) { nombre = new char; nombre = original.getNombre(); cout << "-clase Tanque- Tanque copia creada."<< endl; } // metodo avanzar void Tanque::avanzar(int metros) const { cout << "-clase Tanque-" << this->getNombre() << " avanzando: " << metros << " m." << endl; } // metodo disparar void Tanque::disparar(){ if (proyectiles > 0) { proyectiles--; cout << "-clase Tanque-" << this->getNombre() <<" BOOOOM!!" << endl; } else { cout << "-clase Tanque-" << this->getNombre() << " No queda municion." << endl; } } // funcion principal // Aqui haremos multiples pruebas... int main () { int i, resp; // creamos los Tanques Tanque tanqueta = Tanque(); // podemos sacar lso datos del soldado asi: cout << "El nombre del soldado es: " << (tanqueta.getSoldado()).getNombre()<< endl; tanqueta.avanzar(5); tanqueta.disparar(); tanqueta.getSoldado().matar(); cin >> i; }friend: haciendo amigos
Mediante la palabra reservada friend podemos declara relaciones de confianza entre clases y permitir que una clase amiga pueda acceder a los atributos y metodos privados de esa clase.
Veamos el ejemplo con la Pluma y la Espada. La pluma vence a la espada pero ademas la declara como amiga porque es asi de enrollada. Veamos la declaracion de Pluma:
/** * Pluma.hpp * Clase que define el objeto pluma, un objeto que sirve para escribir * * Pello Xabier Altadill Izura * */ #include <iostream.h> class Pluma { public: Pluma(); Pluma(char *tipo, char *usuario); ~Pluma(); Pluma(Pluma const &); // ATENCION!!! definimos la clase ESPADA como friend // por tanto desde ella se podra acceder a los elementos PRIVADOS de la Pluma friend class Espada; char *getTipo() const { return this->tipo;} char *getUsuario() const { return this->usuario;} private: // metodo para escribir con la pluma void escribe (char *texto) {cout << "escribo con la pluma: " << texto << endl;} void test() { cout << "Mega funcion privada de Pluma!" << endl;} char *tipo; char *usuario; };Y su implementacion:
/** * Pluma.cpp * Programa que implementa la clase Pluma * * Pello Xabier Altadill Izura * Compilacion: g++ -c Pluma.cpp */ #include "Pluma.hpp" // Constructor Pluma::Pluma(): tipo("tinta china"), usuario("Bertrand Russel") { cout << "Pluma construida." << endl; } // Constructor Pluma::Pluma(char *tipo, char *usuario) { this->tipo = tipo; this->usuario = usuario; cout << "Pluma construida de tipo: " << tipo << endl; } // Destructor Pluma::~Pluma() { cout << "Pluma destruida." << endl; } // Constructor copia Pluma::Pluma(Pluma const & original) { tipo = new char; tipo = original.tipo; }Y ahora la declaracion de la Espada
/** * Espada.hpp * Clase que define el objeto Espada, un objeto que sirve para matar * * Pello Xabier Altadill Izura * */ #include <iostream.h>.h class Espada { public: Espada(); Espada(char *tipo); ~Espada(); Espada(Espada const &); // desde este metodo accederemos a la // parte privada de la pluma void usarPluma (char *texto); char *getTipo() const { return this->tipo;} private: char *tipo; };Y su implementacion:
/** * Espada.cpp * Programa que implementa la clase Espada * * Pello Xabier Altadill Izura * * Compilacion: g++ -o Espada Pluma.o Espada.cpp */ #include "Espada.hpp" #include "Pluma.cpp" // Constructor Espada::Espada(): tipo("katana") { cout << "Espada construida." << endl; } // Constructor Espada::Espada(char *tipo) { this->tipo = tipo; cout << "Espada construida de tipo: " << tipo << endl; } // Destructor Espada::~Espada() { cout << "Espada destruida." << endl; } // Constructor copia Espada::Espada(Espada const & original) { tipo = new char; tipo = original.tipo; } // metodo desde el que accedemos a Pluma void Espada::usarPluma(char *texto) { // implementamos una pluma y... Pluma plumilla = Pluma(); // y ahora accedemos a sus miembros privados: atributos ... cout << "La pluma es tipo: " << plumilla.tipo << endl; cout << "Y su usuario es: " << plumilla.usuario << endl; plumilla.escribe(texto); // e incluso a sus metodos! plumilla.test(); } // funcion principal int main () { int i; Espada tizona = Espada("mandoble"); // invocamos un metodo que accedere a la zona privada de la clase tizona.usarPluma("jaja uso la pluma a mi antojo"); cin >> i; return 0; }La funcion amiga
Podemos declarar una funcion como amiga y nos dara acceso a TODO a traves de ese funcion.
Para ilustrar esto definimos las clases Chico y Chica en un unico fichero
/** * ChicoChica.cpp * Clase que define el objeto Chico y Chica. Chico tiene una funcion llamada * esNovio que dentro de chica la declaramos como friend y le dara acceso a todo * * Pello Xabier Altadill Izura * Compilacion: g++ -o ChicoChica ChicoChica.cpp */ #include <iostream.h> class Chico { public: // constructor Chico():nombre("Romeo") {} // constructor Chico(char *nombre) { this->nombre = nombre;} // destructor ~Chico() {} // constructor copia Chico(Chico const & origen) { nombre = new char; nombre = origen.nombre; } // desde este metodo accederemos a la // parte privada de la clase chica void esNovio(); char *getNombre() const { return this->nombre;} private: char *nombre; }; class Chica { public: // constructor Chica(): nombre("Julieta"), edad(23), coeficienteInteligencia(140), medidas("95-60-95") { } // destructor ~Chica() {} // constructor copia Chica(Chica const & origen) { nombre = new char; nombre = origen.nombre; } // Aqui definimos un metodo friend externo // que tendra acceso a toda la clase chica friend void Chico::esNovio(); // otra opcion seria declara Chico como friend: // friend class Chico; private: void pensar() { cout << "estoy pensado..." << endl; } void entrarHabitacion() { cout << "estoy entrando en la habitacion..." << endl; } char *nombre; int edad; int coeficienteInteligencia; char *medidas; }; // implementacion de la funcion del chico esNovio void Chico::esNovio() { Chica neska = Chica(); neska.entrarHabitacion(); cout << "Con esta funcion entro en todo! " << endl; cout << "Dime tu edad real chica: " << neska.edad << endl; cout << "Y tu coeficiente intelectual: " << neska.coeficienteInteligencia << endl; cout << "joder, me parece que no te gustara el futbol." << endl; } // funcion principal, para las pruebas int main () { int i; Chico mutiko = Chico(); // vamos a ver si llamamos a esNovio... mutiko.esNovio(); cin >> i; }