3 junio 2016
3 junio 2016
class CAnimal { public: CAnimal(); // constructor virtual void Sound() = 0; // función virtual pura private: double m_legs_count; // número de patas del animal };Aquí la función Sound() es virtual pura, por eso se la declara con el especificador de función virtual pura PURE (=0).
class CAnimal { public: virtual void Sound()=NULL; // PURE method, debe ser redefinido en la clase derivada, la propia clase CAnimal se ha convertido en abstracta y no puede ser creada }; //--- derivada de la clase abstracta class CCat : public CAnimal { public: virtual void Sound() { Print("Myau"); } // PURE es redefinido, la clase CCat no es abstracta y puede ser creada }; //--- ejemplos de uso incorrecto new CAnimal; // error 'CAnimal' - el compilador retorna el error "cannot instantiate abstract class" CAnimal some_animal; // error 'CAnimal' - el compilador retorna el error "cannot instantiate abstract class" //--- ejemplos de uso correcto new CCat; // no hay error, la clase CCat no es abstracta CCat cat; // no hay error, la clase CCat no es abstractaLimitaciones de uso de las clases abstractas
//+------------------------------------------------------------------+ //| Clase básica abstracta | //+------------------------------------------------------------------+ class CAnimal { public: //--- función virtual pura virtual void Sound(void)=NULL; //--- función void CallSound(void) { Sound(); } //--- constructor CAnimal() { //--- invocación directa del método virtual Sound(); //--- invocación indirecta (a través de una tercera función) CallSound(); //--- en el constructor y/o destructor siempre se invocan sus propias funciones, //--- a pesar del carácter virtual y de la redefinición de la función invocada en la derivada //--- si la función invocada es virtual pura, entonces //--- la invocación provocará el error de ejecución crítico: "pure virtual function call" } };Sin embargo, los constructores y destructores de las clases abstractas pueden invocar otras funciones miembro.
typedef int (*TFunc)(int,int);Ahora TFunc es un tipo y se puede declarar la variable-índice a una función:
TFunc func_ptr;En la variable func_ptr se puede guardar el índice a una función para invocarla más tarde:
int sub(int x,int y) { return(x-y); } int add(int x,int y) { return(x+y); } int neg(int x) { return(~x); } func_ptr=sub; Print(func_ptr(10,5)); func_ptr=add; Print(func_ptr(10,5)); func_ptr=neg; // error: neg no tiene el tipo int (int,int) Print(func_ptr(10)); // error: tiene que haber dos parámetrosLos índices a una función se pueden guardar y transmitir como parámetros. No es posible recibir un índice a un método de clase no estático.