271 likes | 392 Views
Informática II. Clase 10: Clases y funciones especiales. Diego Fernando Serna Restrepo. Semestre 2011/2. Chiste del Día. Contenido. Variables miembro estáticas. 1. Funciones miembro estáticas. 2. Punteros a funciones. 3. Arreglo de punteros a funciones. 4.
E N D
Informática II Clase 10: Clases y funcionesespeciales Diego Fernando Serna Restrepo Semestre 2011/2
Chiste del Día Informática II 2011/2
Contenido Variables miembroestáticas 1 Funcionesmiembroestáticas 2 Punteros a funciones 3 Arreglo de punteros a funciones 4 Informática II 2011/2
Clases y funciones especiales • Hasta ahora se ha estudiado diferentes mecanismos que tiene C++ para manipular variables: variables globales, variables locales de las funciones, punteros a variables y variables miembro. • En C++ existen métodos para que diferentes objetos del mismo tipo puedan compartir variables y funciones. Informática II 2011/2
Datos miembro estáticos Informática II 2011/2
Datos miembro estáticos Buena practica de programación Es preferible definir la variable estática como privada y otorgarle un método de acceso público, sin embargo de esta manera se debe crear primero un objeto para a través de él poder acceder al método. Informática II 2011/2
Datos miembro estáticos • int Cat::HowManyCats = 0; • int main() • { • const intMaxCats = 5; inti; • Cat *CatHouse[MaxCats]; • for (i = 0; i<MaxCats; i++) • CatHouse[i] = new Cat(i); • for (i = 0; i<MaxCats; i++) • { • cout << "There are "; • cout << Cat::HowManyCats; • cout << " cats left!\n"; • cout << "Deleting the one which is "; • cout << CatHouse[i]->GetAge(); • cout << " years old\n"; • delete CatHouse[i]; • CatHouse[i] = 0; • } • return 0; • } #include <iostream> usingnamespacestd; classCat { public: Cat(intage):itsAge(age){HowManyCats++; } virtual ~Cat() { HowManyCats--; } virtual intGetAge() { returnitsAge; } virtual voidSetAge(intage) { itsAge = age; } staticintHowManyCats; private: intitsAge; }; "There are “ 5 catsleft Deletingtheonewhich is 0 yearsold "There are “ 4 catsleft Deletingtheonewhich is 1 yearsold "There are “ 3 catsleft Deletingtheonewhich is 2 yearsold "There are “ 2 catsleft Deletingtheonewhich is 3 yearsold "There are “ 1 catsleft Deletingtheonewhich is 4 yearsold Informática II 2011/2
Tips al usar datos miembros estáticos Informática II 2011/2
Contenido Variables miembroestáticas 1 Funcionesmiembroestáticas 2 Punteros a funciones 3 Arreglo de punteros a funciones 4 Informática II 2011/2
Funciones miembro estáticas Informática II 2011/2
Funciones miembro estáticas • class Cat{ • public: • //…Constructor, destructor , otrosmetodos • static intGetHowMany() { return HowManyCats; } • static intHowManyCats; • }; • int Cat::HowManyCats = 0; • int main() • { • inthowMany; • Cat theCat; // define a cat • howMany = theCat.GetHowMany(); // access through an object • howMany = Cat::GetHowMany(); // access without an object • } Informática II 2011/2
Funciones miembro estáticas • Cuidado, las funciones miembro estáticas NO poseen un puntero this, ni tampoco pueden ser declaradas const. • Como las funciones miembro utilizan el puntero this para acceder a las variables miembro, una función estática solo podrá acceder a los datos miembro que sean declarados estáticos. Informática II 2011/2
Contenido Variables miembroestáticas 1 Funcionesmiembroestáticas 2 Punteros a funciones 3 Arreglo de punteros a funciones 4 Informática II 2011/2
Punteros a funciones • Así como el nombre de un arreglo es un puntero constante al primer elemento del arreglo, el nombre de una función es un puntero constante a la función. • Es posible declarar entonces una variable puntero que apunte a un función e invocar o llamar a la función original a través de él. Esto puede ser muy útil, al permitir crear programas que decidan qué función llamar basándose en la elección del usuario en tiempo de ejecución. Informática II 2011/2
Punteros a funciones • Un puntero a función debe apuntar siempre a una función con el mismo tipo de retorno y firma. long (* funcPtr) (int); funcPtr: es declarado para ser un puntero que apunta a una función que toma un entero int como parámetro de entrada y retorna un long. El paréntesis al rededor de * funcPtr es necesario Informática II 2011/2
Punteros a funciones Para asignar un puntero a una función, simplemente se iguala este al nombre de la función. • void (* pFunc) (int &, int &); //puntero a funcion • void GetVals(int&, int&); //funcion • pFunc = GetVals; //puntero a funciongetVals Para hacer el llamado a la función a través del puntero, simplemente use el puntero a función de la misma forma como usaría el nombre de la función • pFunc(valOne, valTwo); //llamdo de la funcion Informática II 2011/2
Punteros a funciones • void PrintVals(int x, int y) { • cout << "x: " << x << " y: " << y << endl; • } • void Square (int & rX, int & rY) { • rX *= rX; rY *= rY; • } • void Cube (int & rX, int & rY) { • inttmp; tmp = rX; • rX *= rX; rX = rX * tmp; • tmp = rY; rY *= rY; • rY = rY * tmp; • } • void Swap(int & rX, int & rY) { • int temp; temp = rX; • rX = rY; rY = temp; • } • void GetVals (int & rValOne, int & rValTwo){ • cout << "New value for ValOne: "; • cin >> rValOne; • cout << "New value for ValTwo: "; • cin >> rValTwo; • } • int main() • { • void (* pFunc) (int &, int &); • boolfQuit = false; • intvalOne=1, valTwo=2; • int choice; • while (fQuit == false) • { • cout << "(0)Quit (1)Change Values (2)Square • (3)Cube (4)Swap: "; • cin >> choice; • switch (choice) • { • case 1: pFunc = GetVals; break; • case 2: pFunc = Square; break; • case 3: pFunc = Cube; break; • case 4: pFunc = Swap; break; • default : fQuit = true; break; • } • if (fQuit) • break; • PrintVals(valOne, valTwo); • pFunc(valOne, valTwo); • PrintVals(valOne, valTwo); • } • return 0; • } • #include <iostream> • using namespace std; • void Square (int&,int&); • void Cube (int&, int&); • void Swap (int&, int &); • void GetVals(int&, int&); • void PrintVals(int, int); Informática II 2011/2
Punteros a funciones • // Listing 14.6 Without function pointers • #include <iostream>int main() • { • boolfQuit = false; • intvalOne=1, valTwo=2; • int choice; • while (fQuit == false) • { • cout << "(0)Quit (1)Change Values (2)Square(3)Cube (4)Swap: "; • cin >> choice; • switch (choice) • { • case 1: • PrintVals(valOne, valTwo); • GetVals(valOne, valTwo); • PrintVals(valOne, valTwo); • break; • case 2: • PrintVals(valOne, valTwo); • Square(valOne,valTwo); • PrintVals(valOne, valTwo); • break; • case 3: • PrintVals(valOne, valTwo); • Cube(valOne, valTwo); • PrintVals(valOne, valTwo); • break; • case 4: • PrintVals(valOne, valTwo); • Swap(valOne, valTwo); • PrintVals(valOne, valTwo); • break; • default : • fQuit = true; • break; • } • if (fQuit) • break; • } • return 0; • } • Los punteros a funciones reducen código duplicado, clarifican el programa, y permite hacer tablas de funciones a llamar en tiempo de ejecución. Informática II 2011/2
int main() • { • intvalOne=1, valTwo=2; • int choice; • boolfQuit = false; • void (*pFunc)(int&, int&); • while (fQuit == false) • { • cout << "(0)Quit (1)Change Values • (2)Square (3)Cube (4)Swap: "; • cin >> choice; • switch (choice) • { • case 1:pFunc = GetVals; break; • case 2:pFunc = Square; break; • case 3:pFunc = Cube; break; • case 4:pFunc = Swap; break; • default:fQuit = true; break; • } • if (fQuit == true) • break; • PrintVals ( pFunc, valOne, valTwo); • } • return 0; • } Pasando como argumento a una función, punteros a funciones • #include <iostream> • using namespace std; • void Square (int&,int&); • void Cube (int&, int&); • void Swap (int&, int &); • void GetVals(int&, int&); • void PrintVals(void (*)(int&, int&),int&, int&); • Los punteros a funciones pueden ser pasados como argumentos a otras funciones, las cuales a su vez pueden llamar a otra función usando el puntero. • void PrintVals( void (*pFunc)(int&, int&),int& x, int& y) • { • cout << "x: " << x << " y: " << y << endl; • pFunc(x,y); • cout << "x: " << x << " y: " << y << endl; • } Informática II 2011/2
Pasando como argumento a una función, punteros a funciones • Se puede usar typedef para simplificar las definiciones de punteros a funciones • typedef void (*VPF) (int&, int&) ; • VPF pFunc; • VPF pFunc2; • void (*pFunc3)(int&, int&); • void (*pFunc4)(int&, int&); Informática II 2011/2
Punteros a métodos de una clase Informática II 2011/2
#include <iostream> • using namespace std; • class Mammal • { • public: • Mammal():itsAge(1) { } • virtual ~Mammal() { } • virtual void Speak() const = 0; • virtual void Move() const = 0; • protected: • intitsAge; • }; • int main() • { • void (Mammal::*pFunc)() const =0; • Mammal* ptr =NULL; • int Animal; • int Method; • boolfQuit = false; • while (fQuit == false) • { • cout << "(0)Quit (1)dog (2)cat (3)horse: "; • cin >> Animal; • switch (Animal) • { • case 1: ptr = new Dog; break; • case 2: ptr = new Cat; break; • case 3: ptr = new Horse; break; • default: fQuit = true; break; • } • if (fQuit) break; • cout << "(1)Speak (2)Move: "; • cin >> Method; • switch (Method) • { • case 1: pFunc = Mammal::Speak(); break; • default: pFunc = Mammal::Move(); break; • } • (ptr->*pFunc)(); • delete ptr; • } • return 0; • } • class Dog : public Mammal{ • public: • void Speak()const { cout << "Woof!\n"; } • void Move() const { cout << "Walking ...\n"; } • }; Punteros a métodos de una clase • class Cat : public Mammal { • public: • void Speak()const { cout << "Meow!\n"; } • void Move() const { cout << "slinking...\n"; } • }; • class Horse : public Mammal { • public: • void Speak()const { cout << "Whinny!\n"; } • void Move() const { cout << "Galloping...\n"; } • }; Informática II 2011/2
Usando Arreglos de punteros a métodos de una clase. Llame los punteros referenciados a las funciones miembro de un objeto específico de una clase, usando typedefpara hacer la definición de los punteros y las declaraciones más fácil de leer. Informática II 2011/2
//Listing 14.11 Array of pointers to member functions • #include <iostream> • using namespace std; • class Dog • { • public: • void Speak()const { cout << "Woof!\n"; } • void Move() const { cout << "Walking to heel...\n"; } • void Eat() const { cout << "Gobbling food...\n"; } • void Growl() const { cout << "Grrrrr\n"; } • void Whimper() const { cout << "Whining noises...\n"; } • void RollOver() const { cout << "Rolling over...\n"; } • void PlayDead() const { cout << "Is this the end of Little dog?\n"; } • }; Usando Arreglos de punteros a métodos de una clase. • typedef void (Dog::*PDF)()const ; • int main() • { • const intMaxFuncs = 7; • PDF DogFunctions[MaxFuncs] = • { Dog::Speak, Dog::Move, Dog::Eat, Dog::Growl, • Dog::Whimper, Dog::RollOver, Dog::PlayDead }; • Dog* pDog =NULL; • int Method; • boolfQuit = false; • while (!fQuit) • { • cout << "(0)Quit (1)Speak (2)Move (3)Eat (4)Growl"; • cout << " (5)Whimper (6)Roll Over (7)Play Dead: "; • cin >> Method; • if (Method == 0) • { • fQuit = true; • } • else • { • pDog = new Dog; • (pDog->*DogFunctions[Method-1])(); • delete pDog; • } • } • return 0; • } Informática II 2011/2
GRACIAS POR SU ATENCIÓN Informática II 2011/2
Bibliografía • Pagina de Referencia lenguaje C++: • http://www.cplusplus.com/reference/std/exception/exception/ • http://www.cplusplus.com/reference/std/stdexcept/ • SamsTeach yourselft C++ in 21 days: http://newdata.box.sk/bx/c/htm/ch20.htm#Heading1 Informática II 2011/2
Gracias ! Informática II 2009/2