Miembros estaticos

Quereis ver un miembro no estatico? (< !-- nota docbook: quitar chorradas antes de publicar -->) Variables/Funciones estaticas Dentro de las clases podemos definir atributos y metodos estaticos. Tienen de particular que son accesibles sin necesidad de definir una clase y que su valor es EL MISMO en todas los objetos que se vayan creando de una clase. Es como una variable global de una clase. Con este ejemplo se ve su uso, y de paso se revisa el tema de punteros a funciones. (si, has leido bien).

/**
* Soldado.hpp
* Clase que define el objeto soldado muestra el uso de variables estaticas
* y metodos estaticos. Todo lo estatico escapa del ambito de la clase y puede
* ser invocado desde el exterior
*
* Pello Xabier Altadill Izura
*
*/

using namespace std;
#include <iostream>

class Soldado {

public:

	// constructores
	Soldado();

	Soldado(char *nombre, int unidad);

	// destructor
	~Soldado();

	// copia
	Soldado(Soldado const &);

	// get/set
	char *getNombre () const { return this->nombre; }

	void setNombre (char *nombre) { this->nombre = nombre; }

	int getUnidad () const { return this->unidad; }

	void setUnidad (int unidad) { this->unidad = unidad; }

	void matar() const;

	void darOrden (char *orden) const;

	// metodo que toma como parametro una funcion
	void ejecutaAccion ( void (*accion) (int,int));

	static int TotalSoldados; // variable estatica!

	static int TotalBalas; // variable estatica!
	

	// Funciones estaticas
	static int getTotalSoldados () { return TotalSoldados; }
	
	static int getTotalBalas () { return TotalBalas; }


private:
	
	char *nombre;
	
	int unidad;

};

Y su implementacion. Se recomienda probar y ejecutar para comprobar el funcionamiento de las variables estaticas.

/**
* Soldado.cpp
* Programa que implementa la clase Soldado
* 
* Pello Xabier Altadill Izura
* Compilacion: g++ Soldado.cpp -o Soldado
*/

#include "Soldado.hpp"

// Constructor
Soldado::Soldado(): nombre("Ryan"), unidad(101) {

	TotalSoldados += 1;
	TotalBalas++;
	cout << "Soldado " << nombre << " construido. Unidad: " << unidad << endl;

}


// Constructor parametrizado
Soldado::Soldado(char *nombre, int unidad) {
	
	TotalSoldados++;
	TotalBalas++;
	this->nombre = nombre;
	this->unidad = unidad;
	cout << "Soldado " << nombre << " :Soldado construido." << endl;

}


// Destructor
Soldado::~Soldado() {
	
	TotalSoldados--;
	cout << "Soldado "<< this->getNombre() << " destruido."<< endl;

}


// constructor copia
Soldado::Soldado(const Soldado & original) {
	
	nombre = new char;
	nombre = original.getNombre();
	cout << "-clase Soldado- Soldado copia creada."<< endl;

}


// metodo matar
void Soldado::matar() const {
	
	TotalBalas--;
	cout << this->getNombre() << " Matar es lo mio " << endl;
	cout << "Born to kill. paz. Es por la dualidad de Kant" << endl;

}

// metodo darOrden
void Soldado::darOrden(char *orden) const {

	cout << "Recluta patoso!" << endl; 
	cout << this->getNombre() << " unidad " << this->getUnidad() << " ordena: ";
	cout << orden << endl;

}


// metodo ejecutaAccion: ejecuta la funcion que se le pasa como parametro
void Soldado::ejecutaAccion ( void (*accion) (int,int)) {
	
	accion(5,7);
	
	cout << "Recluta patoso!" << endl; 

} 


// ATENCION IMPORTANTE: HAY QUE DEFINIR E INICIAR LAS VARIABLES ESTATICA SI NO
// el compilador nos puede poner pegas
int Soldado::TotalSoldados = 0;
int Soldado::TotalBalas = 0;

// Definimos una funcion ajena a la clase desde la cual accederemos
// a la variable estatica, con lo que se demuestra que la variable estatica
// esta fuera de la "capsula" de la clase.
void recuentoSoldados(void);

// definimos otra funcion esta para pasarsela como parametro a un metodo de la clase
void carga (int balas, int granadas);


// funcion principal
// Aqui haremos multiples pruebas...
int main () { 

	int i, resp;

	// creamos los soldados
	Soldado peloton[10];
	Soldado Hanks = Soldado("Hanks",105);

	// definicion de puntero de funcion:
	void (*funcion) (int, int) = carga; 
	
	// Si hay mas de una funcion carga sera la que tenga los mismos parametros
	// y el mismo tipo de retorno

	// llamamos a la funcion recuento
	recuentoSoldados();
	
	peloton[0].darOrden("Todos en formacion.");
	
	peloton[2].darOrden("Canta el colacao!");
	
	// recorremos los 10 soldados y hacemos algo dependiendo de la entrada
	// Si matamos unos cuantos modificaremos la variable de TotalSoldados
	
	for (i = 0; i < 10 ; i++) {
	
		cout << "Elije 0 o cualquier otro numero: " << endl;
		cin >> resp;
		
		if (resp == 0) {
			
			// matamos al soldado
			peloton[i].~Soldado();

		} else {
			
			peloton[i].matar(); // tiramos una bala
		}
		
		// Invocamos el metodo estatico?
		// es un acceso DIRECTO sin necesitar un objeto definido
		resp = Soldado::getTotalSoldados();
		cout << "Cuantos quedan? " << resp << endl;

	}//for

	// accedemos directamente a variable estatica
	cout << "Total balas antes de recarga: " << 

	Soldado::TotalBalas << endl;
	
	// hacemos una recarga:
	Hanks.ejecutaAccion(funcion);
	
	// llamamos a la funcion recuento
	recuentoSoldados();


	return 0;

}


// implementacion de la funcion recuento
// muestra el numero de soldados. Podemos acceder DIRECTAMENTE a la variable statica
void recuentoSoldados () {
	
	cout << "Cuantos soldados quedan vivos? " << endl;
	cout << "En total: " << Soldado::TotalSoldados << " soldados"<< endl;
	
	cout << "Municion? " << endl;
	cout << "En total: " << Soldado::getTotalBalas() << " balas" << endl;

}


// funcion que carga municion del peloton
void carga (int balas, int granadas) {
	
	cout << "Cargando balas: " << balas << endl;
	
	Soldado::TotalBalas += balas ;
	
	cout << "Cargando granadas: " << granadas << endl;

}

Bueno, y con esto ya son dos semanas dandole al c++ y aprendiendo su abc...