113
POLIMORFISMO Cristina Cachero, Pedro J. Ponce de León 4 Sesiones (6 horas) Versión 0.9 TEMA 4 Depto. Lenguajes y Sistemas Informáticos

4-Polimorfismo

Embed Size (px)

Citation preview

  • POLIMORFISMO

    Cristina Cachero, Pedro J. Ponce de Len

    4 Sesiones (6 horas)Versin 0.9

    TEMA 4

    Depto. Lenguajes y Sistemas Informticos

  • Curso 07-08 2

    Tema 4. PolimorfismoObjetivos bsicos

    Comprender el concepto de polimorfismo Conocer y saber utilizar los diferentes tipos de polimorfismo. Comprender el concepto de enlazado esttico y dinmico en los

    lenguajes OO. Comprender la relacin entre polimorfismo y herencia en los lenguajes

    fuertemente tipados. Apreciar la manera en que el polimorfismo hace que los sistemas sean

    extensibles y mantenibles.

  • Curso 07-08 3

    Indice1. Motivacin y conceptos previos

    Signatura y mbito Tiempo de enlace

    2. Polimorfismo y reutilizacin Definicin Tipos de polimorfismo

    3. Sobrecarga Sobrecarga basada en mbito Sobrecarga basada en signatura de tipo Alternativas a la sobrecarga

    4. Polimorfismo en jerarquas de herencia Redefinicin Shadowing Sobrescritura

    5. Variables polimrficas La variable receptora Downcasting Polimorfismo puro

    6. Genericidad Funciones genricas en C++ Plantillas de clase en C++ Herencia en clases genricas

  • Curso 07-08 4

    1. Motivacin

    Objetivo de la POO Aproximarse al modo de resolver problemas en el mundo

    real.

    El polimorfismo es el modo en que los lenguajes OOimplementan el concepto de polisemia del mundoreal: Un nico nombre para muchos significados, segn el

    contexto.

  • Curso 07-08 5

    1. Conceptos previos:Signatura

    Signatura de tipo de un mtodo:

    Descripcin de los tipos de sus argumentos, su orden yel tipo devuelto por el mtodo.

    Notacin: Omitimos el nombre del mtodo, el de la clase a la que

    pertenece (el tipo del receptor)

    Ejemplosdouble power (double base, int exp)

    double*int doublebool Casilla::setPieza(Pieza& p)

    Pieza bool

  • Curso 07-08 6

    1. Conceptos previos:mbito mbito de un nombre:

    Porcin del programa en la cual un nombre puede ser utilizado de unadeterminada manera.

    Ejemplo:double power (double base, int exp) La variable base slo puede ser utilizada dentro del mtodo power

    mbitos activos: puede haber varios simultneamenteclass A { int x,y; public: void f() { // mbitos activos: // GLOBAL // CLASE (atribs. de clase y de instancia) // METODO (argumentos, var. locales) if () { string s; // LOCAL (var. locales) }}

  • Curso 07-08 7

    1. Conceptos previos:Tiempo de enlace

    Momento en el que se identifica el fragmento de cdigo a ejecutar asociado aun mensaje (llamada a mtodo) o el objeto concreto asociado a una variable.

    Tiempo de Compilacin: Enlace esttico (early binding) EFICIENCIA

    Tiempo de Ejecucin: Enlace dinmico (late binding): FLEXIBILIDAD

    Aplicable a: OBJETOS:

    Con enlace esttico el tipo de objeto que contiene una variable se determina entiempo de compilacin.

    Con enlace dinmico el tipo de objeto al que hace referencia una variable no estpredefinido, por lo que el sistema gestionar la variable en funcin de la naturaleza realdel objeto que referencie en cada momento.

    Lenguajes como Smalltalk siempre utilizan enlace dinmico con variables C++ slo permite enlace dinmico con variables cuando stos son punteros, y

    slo dentro de jerarquas de herencia. OPERACIONES:

    Con enlace esttico la eleccin de qu mtodo ser el encargado de responder a unmensaje se realiza en tiempo de compilacin, en funcin del tipo que tena el objetodestino de la llamada en tiempo de compilacin.

    Con enlace dinmico la eleccin de qu mtodo ser el encargado de responder a unmensaje se realiza en tiempo de ejecucin, en funcin del tipo correspondiente alobjeto que referencia la variable mediante la que se invoca al mtodo en el instanteactual.

  • Curso 07-08 8

    1. Conceptos previos:Tiempo de enlace El tipo de lenguaje utilizado (fuertemente o dbilmente tipado)

    determina su soporte al enlace dinmico:

    Lenguaje fuertemente tipado Lenguajes Procedimentales: no soportan enlace dinmico: el tipo de toda

    expresin (identificador o fragmento de cdigo) se conoce en tiempo decompilacin.

    LOO: slo soportan enlace dinmico dentro de la jerarqua de tipos a laque pertenece toda expresin (identificador o fragmento de cdigo) establecidaen tiempo de compilacin.

    Lenguaje dbilmente tipado S soportan enlace dinmico: el enlace entre variables y tipo (sin

    restricciones) se efecta en tiempo de ejecucin (variables se compilan sinasignarles tipo concreto).

  • Curso 07-08 9

    Indice1. Motivacin y conceptos previos

    Signatura y mbito Tiempo de enlace

    2. Polimorfismo y reutilizacin Definicin Tipos de polimorfismo

    3. Sobrecarga Sobrecarga basada en mbito Sobrecarga basada en signatura de tipo Alternativas a la sobrecarga

    4. Polimorfismo en jerarquas de herencia Redefinicin Shadowing Sobrescritura

    5. Variables polimrficas La variable receptora Downcasting Polimorfismo puro

    6. Genericidad Funciones genricas en C++ Plantillas de clase en C++ Herencia en clases genricas

  • Curso 07-08 10

    2. PolimorfismoDefinicin

    Capacidad de una entidad de referenciar distintos elementosen distintos instantes de tiempo.

    El polimorfismo nos permite programar de manera general en lugarde programar de manera especfica.

    Hay cuatro tcnicas, cada una de las cuales permite una formadistinta de reutilizacin de software, que facilita a su vez eldesarrollo rpido, la confianza y la facilidad de uso y mantenimiento.

    Sobrecarga Sobreescritura Variables polimrficas Genericidad

  • Curso 07-08 11

    Tipos de polimorfismo

    Sobrecarga (Overloading, Polimorfismo ad-hoc): un solo nombre demtodo y muchas implementaciones distintas. Las funciones sobrecargadas normalmente se distinguen en tiempo de

    compilacin por tener distintos parmetros de entrada y/o salida. Sobreescritura (Overriding, Polimorfismo de inclusin): Tipo especial

    de sobrecarga que ocurre dentro de relaciones de herencia. En este caso la signatura es la misma (refinamiento o reemplazo del mtodo

    del padre) pero los mtodos se encuentran en dos clases distintasrelacionadas mediante herencia.

    Variables polimrficas (Polimorfismo de asignacin): variable que sedeclara como de un tipo pero que referencia en realidad un valor de untipo distinto. Cuando una variable polimrfica se utiliza como argumento, la funcin

    resultante se dice que exhibe un polimorfismo puro. Genericidad (plantillas o templates): forma de crear herramientas

    de propsito general (clases, mtodos) y especializarlas para situacionesespecficas.

  • Curso 07-08 12

    Tipos de polimorfismo

    SobrecargaFactura::imprimir()Factura::imprimir(int numCopias)ListaCompra::imprimir()

    SobreescrituraCuenta::abonarInteres()CuentaJoven::abonarInteres()

    Variables polimrficasCuenta *pc=new CuentaJoven();

    GenericidadListaListaListaLista

  • Curso 07-08 13

    Indice1. Motivacin y conceptos previos

    Signatura y mbito Tiempo de enlace

    2. Polimorfismo y reutilizacin Definicin Tipos de polimorfismo

    3. Sobrecarga Sobrecarga basada en mbito Sobrecarga basada en signatura de tipo Alternativas a la sobrecarga

    4. Polimorfismo en jerarquas de herencia Redefinicin Shadowing Sobrescritura

    5. Variables polimrficas La variable receptora Downcasting Polimorfismo puro

    6. Genericidad Funciones genricas en C++ Plantillas de clase en C++ Herencia en clases genricas

  • Curso 07-08 14

    3. Sobrecarga (Overloading, polimorfismo ad-hoc )

    Un mismo nombre de mensaje asociado a varias implementaciones La sobrecarga se realiza en tiempo de compilacin (enlace esttico)

    en funcin de la signatura completa del mensaje.

    Dos tipos de sobrecarga: Basada en mbito: Mtodos con diferentes mbitos de definicin,

    independientemente de sus signaturas de tipo. Permitido en todos loslenguajes OO.

    Un mismo mtodo puede ser utilizado en dos o ms clases. P. ej. Sobrecarga de operadores como funciones miembro.

    Basada en signatura:Mtodos con diferentes signaturas de tipo en elmismo mbito de definicin. No permitido en todos los lenguajes OO.

    P. ej. Cualquier conjunto de funciones no miembro (en el mbito de definicinglobal) que comparten nombre.

    Dos o ms mtodos en la misma clase pueden tener el mismo nombre siempreque tengan distinta signatura de tipos.

  • Curso 07-08 15

    Distintos mbitos implican que el mismo nombre de mtodo puedeaparecer en ellos sin ambigedad ni prdida de precisin.

    La sobrecarga por mbito no requiere que las funciones asociadas conun nombre sobrecargado tengan ninguna similitud semntica, ni lamisma signatura de tipo.

    Ejemplos Son Profesor y Alumno a mbitos distintos? Y Pers y Profesor?

    Sobrecarga basada en mbito

    Carta

    +dibuja()Pers

    Profesor

    +getNombre()

    Alumno

    +getNombre()

    Baraja

    +dibuja(int nMontones=1)

    Maratn

    +getDistancia()

    Lnea

    +getDistancia()

  • Curso 07-08 16

    Mtodos en el mismo mbito pueden compartir el mismo nombresiempre que difieran en nmero, orden y, en lenguajes con tipadoesttico, el tipo de los argumentos que requieren.

    Este estilo ocurre en muchos lenguajes funcionales, en algunos imperativos(e.g. ADA) y en lenguajes OO como C++, C#, Java, Delphi Pascal o CLOS

    C++ permite esta sobrecarga de manera implcita siempre que la seleccindel mtodo requerido por el usuario pueda establecerse de manera noambigua en tiempo de compilacin.

    Esto implica que la signatura no puede distinguirse slo por el tipo de retorno

    Sobrecarga basada en signaturas de tipo

    Suma

    +add(int a)

    +add(int a, int b)

    +add(int a, int b, int c)

  • Curso 07-08 17

    Este modo de sobrecarga en tiempo de compilacin puede dar lugar aresultados inesperados:

    class Padre{};

    class Hijo: public Padre{};

    void Test (Padre *p) {cout tipo;

    if (tipo==1) obj=new Padre();

    else obj=new Hijo(); //ppio de sustitucin

    Test (obj); //a quin invoco?}

    Sobrecarga basada en signaturas de tipo

  • Curso 07-08 18

    No todos los LOO permiten la sobrecarga:

    Permiten sobrecarga de mtodos y operadores: C++

    Permiten sobrecarga de mtodos pero no de operadores: Java,Python, Perl

    Permiten sobrecarga de operadores pero no de mtodos: Eiffel

    Sobrecarga basada en signaturas de tipo

  • Curso 07-08 19

    Dentro de la sobrecarga basada en signaturas de tipo, tieneespecial relevancia la sobrecarga de operadores

    Uso: Utilizar operadores tradicionales con tipos definidos por el usuario. Hay que ser cuidadoso con su uso, pues puede dificultar la comprensin del

    cdigo si se utilizan en un sentido distinto al habitual.

    Forma de sobrecargar un operador @: operator@()

    Para utilizar un operador con un objeto de tipo definido por usuario,ste debe ser sobrecargado. Excepciones: operador de asignacin (=) y el operador de direccin (&)

    El operador direccin (&) por defecto devuelve la direccin del objeto. El operador asignacin por defecto asigna campo a campo.

    Sobrecarga de operadores en C++

  • Curso 07-08 20

    Sobrecarga de operadores en C++

    En la sobrecarga de operadores no se puede cambiar Precedencia (qu operador se evala antes) Asociatividad a=b=c a=(b=c) Aridad (operadores binarios para que acten como unarios o viceversa)

    No se puede crear un nuevo operador

    No se pueden sobrecargar operadores para tipos predefinidos.

    Se pueden sobrecargar todos los operadores definidos en C++ comounarios y binarios excepto ".", ".*", "::, sizeof.

    "?: es el nico operador ternario definido en C++, y no puede sersobrecargado

  • Curso 07-08 21

    Sobrecarga de operadores en C++

    La sobrecarga de operadores se puede realizar mediantefunciones miembro o no miembro de la clase. Como funcin miembro: el operando de la izquierda (en un operador

    binario) debe ser un objeto (o referencia a un objeto) de la clase:

    Complejo Complejo::operator+(const Complejo&)

    Complejo c1(1,2), c2(2,-1);

    c1+c2; // c1.operator+(c2);c1+c2+c3; // c1.operator+(c2).operator+(c3)

  • Curso 07-08 22

    Sobrecarga de operadores en C++

    Sobrecarga de operador como funcin no miembro:

    1. Cuando el operando de la izquierda no es miembro de la clase

    ostream& operator(istream&, Complejo&);

    Complejo c;cout >(cin,c)

    2. Por claridad

    Complejo operator+(const Complejo&, const Complejo&);

  • Curso 07-08 23

    Sobrecarga de operadores en C++

    En C++, los operadores "=", "[]", "->", "()", "new" y "delete", slo puedenser sobrecargados cuando se definen como miembros de una clase.

    Si un operador tiene formatos unarios y binarios (+,&), ambosformatos pueden ser sobrecargados.

  • Curso 07-08 24

    Sobrecarga de operadores en C++Operadores unarios Sobrecarga de operadores unarios:

    Los operadores unarios pueden ser sobrecargados sin argumentos o conun argumento

    Usualmente son implementados como funciones miembro. operator() ;

    Ejemplo:

    TiempoTiempo::operator++()// PREINCREMENTO{ minuto++; if (minuto >= 60) { minuto = minuto - 60; hora++; } return *this;}

    class Tiempo{ public: Tiempo(int, int); void mostrar(); Tiempo operator++(); private: int hora; int minuto;};

  • Curso 07-08 25

    Sobrecarga de operadores en C++Operadores unarios

    Tiempo Tiempo::operator++(int x){ Tiempo aux(*this); minuto++; if (minuto >= 60){ minuto = minuto - 60; hora++; } return aux;}void main(){

    Tiempo t1(17,9);t1.mostrar();//??(t1++).mostrar();//??t1.mostrar();//??(++t1).mostrar();//??t1.mostrar();//??

    }

    class Tiempo{ public: Tiempo(int, int); void mostrar(); Tiempo operator++();//pre Tiempo operator++(int);//post//el argumento int distingue una//versin de la otra private: int hora; int minuto;};

    Cul sera la salida de esteprograma?

    Sobrecarga del mismo modo eloperador -- (predecremento ypostdecremento)

  • Curso 07-08 26

    class TPunto {public: TPunto (int, int);private :

    int x;int y;

    };

    Se desea que el operador ! indiquetrue si x e y son diferentes y false encaso contrario.

    Sobrecarga de operadores en C++Ejercicio: operadores unarios

  • Curso 07-08 27

    Sobrecarga de operadores en C++Operadores binarios

    Funciones no miembro: dos argumentos (ambos operandos) operator(,) ;

    Pueden ser funcin amiga

    Funciones miembro: un solo argumento (operando de la derecha) operator();

    OBJETIVO:

    int main(){ Tiempo t1,t2,tsuma; tsuma=t1+t2; tsuma.mostrar();}

    class Tiempo{ public: Tiempo(int h=0, int m=0) {hora=h; minuto=m;}; void mostrar(){ cout

  • Curso 07-08 28

    Sobrecarga de operadores en C++Operadores binarios

    TiempoTiempo::operator+(const Tiempo &t){ Tiempo aux;

    aux.minuto = minuto + t.minuto; aux.hora = hora + t.hora; if (aux.minuto >= 60) { aux.minuto = aux.minuto - 60; aux.hora++; } return aux;}

    intmain(){ Tiempo T1(12,24); Tiempo T2(4,45);

    T1 = T1 + T2;//T1=T1.operator+(T2) T1.mostrar();}

  • Curso 07-08 29

    Sobrecarga de operadores en C++Ejemplo: clase Cadenaclass Cadena{ public: Cadena(); Cadena(char *); ~Cadena(); void mostrar() const; private: char *cadena; int longitud;};

    Cadena::Cadena(){ cadena = NULL; longitud=0;};

    Cadena::Cadena(char *cad){ cadena = new char[strlen(cad)+1]; strcpy(cadena,cad); longitud = strlen(cad);}Cadena::~Cadena(){ if(cadena!=NULL) delete[] cadena; longitud = 0;}void Cadena::mostrar() const{ cout

  • Curso 07-08 30

    Sobrecarga de operadores en C++Ejemplo: clase CadenaCadenaCadena::operator+(const Cadena &c){ Cadena aux;

    aux.cadena = new char[strlen(c.cadena)+strlen(cadena)+1]; strcpy(aux.cadena,cadena); strcat(aux.cadena,c.cadena); aux.longitud = strlen(cadena)+strlen(c.cadena); return aux;}

    int main(){ Cadena C1("Primera parte"), C2("Segunda Parte"), C3; C3 = C1+C2; //C3.operator=(C1.operator+(C2)); return (0);}

    Funcionara bien esta suma sin definirnada ms, tal y como ocurra en Tiempo?

  • Curso 07-08 31

    Sobrecarga de operadores en C++Ejemplo: clase Cadena y operador = Solucin: SOBRECARGAR EL OPERADOR DE ASIGNACIN

    Cadena& Cadena::operator=(const Cadena &c){ if(this != &c){ if (cadena!=NULL) delete[] cadena; if (c.cadena!=NULL){

    cadena = new char[strlen(c.cadena)+1]; strcpy(cadena,c.cadena);

    longitud = c.longitud; }

    else{ cadena = NULL;

    longitud = 0; } }//end (this != &c)

    return (*this);}

  • Curso 07-08 32

    Sobrecarga de operadores en C++Ejemplo: clase Cadena y C. Copia Solucin: SOBRECARGAR EL CONSTRUCTOR DE COPIA

    Cadena::Cadena(const Cadena &c)

    {

    cadena = NULL; *this = c;

    }

    Corolario: Cuando nuestras clases tengan variables de instancia que sean punteros

    a memoria dinmica debemos sobrecargar siempre el operador deasignacin y el constructor de copia, ya que nunca sabemos cundopuede ser invocado sin que nos demos cuenta.

  • Curso 07-08 33

    Dado el siguiente cdigo:

    class TPunto { TPunto (int x=0, int y=0){

    this->x=x;this->y=y;

    };private :

    int x,y;};

    Se pide: Declara (.h) y define (.cpp) la sobrecarga del operador+= para la clase TPunto. Haz lo mismo suponiendo que no podemos aadirfunciones miembro a la clase.

    Sobrecarga de operadores en C++Ejercicio: operadores binarios

    int main(){ TPunto p1(1,2), p2(3,4); p1+=p2; return(0);}

  • Curso 07-08 34

    Sobrecarga de operadores en C++Operadores de entrada y salida La posibilidad de sobrecarga de los operadores > (entrada)

    resuelve el problema tradicional de libreras de I/O pensadas para trabajarexclusivamente con tipos predefinidos (built-in)

    La abstraccin flujo de salida (ostream) representa una entidad queacepta una secuencia de caracteres. Esa entidad puede luego convertirse enun fichero, una ventana o una red. La abstraccin flujo de entrada(istream) representa una entidad que enva una secuencia de caracteres.Esa entidad puede luego convertirse en un teclado, un fichero o una red.

    La librera estndar proporciona una coleccin de definicionessobrecargadas para el operador > ostream& operator

  • Curso 07-08 35

    Sobrecarga de operadores en C++Operadores de entrada y salida La extensin de esta librera para otros tipos de datos sigue el mismo

    patrn: ostream& operator > (istream& i, &t) Para que esta funcin tenga acceso a la parte privada/protegida de t,

    deberemos definirla como friend de la clase . Ojo! En cualquier caso debe tratarse de una funcin no miembro, ya que

    el operador de la izquierda no es un objeto de la clase.

    class Tiempo{ friend ostream &operator(istream &,Tiempo &); public: private: int hora; int minuto;};

  • Curso 07-08 36

    Sobrecarga de operadores en C++Ejemplo: operadores I/O en clase Tiempo#include using namespace std;ostream& operator t.minuto; // 14 59 return e;}

    void main(){Tiempo T1,T2(17,36),T3;cin >> T1; //operator>>(istream&, Tiempo&)

    // operator>>(cin,T1);T3 = T1 + T2;cout

  • Curso 07-08 37

    class TPunto {public: TPunto (int, int);private :

    int x;int y;

    };

    // OBJETIVOint main(){ TPunto p1(1,2), p2(3,4); cout

  • Curso 07-08 38

    // .hclass TPunto {

    friend ostream& operator

  • Curso 07-08 39

    class TPunto {public: TPunto (int, int);private :

    int x;int y;

    };

    // OBJETIVO 2int main(){ TPunto p1(1,2), p2(3,4); //La llamada cin>>p1 se interpreta como operator>>(cin, p1); cin >> p1; cin >> p2; cout

  • Curso 07-08 40

    istream&operator>>(istream &i, TPunto &p){

    // Lee en formato (x-y)i.ignore(); // Salta el (i >> p.x;i.ignore(); // salta el -i >> p.y;i.ignore(); // salta el )return i;

    }

    Sobrecarga de operadores en C++Ejemplo: operadores I/O en clase TPunto

  • Curso 07-08 41

    Sobrecarga de operadores en C++Ejemplo: operador [] en clase Vector Signatura operador corchete ([])

    & operator[] (int ndice)

    Ejemplo:

    class Vector{ public: Vector( int ne=1) { num = ne; pV = new int[ num]; }; ~Vector(){ delete [] pV; pV=NULL;}; int& operator[](int i) {return pV[ i];};

    private: int *pV; // puntero al 1 elemento int num; // num de elementos};

  • Curso 07-08 42

    Sobrecarga de operadores en C++Ejemplo: operador [] en clase Vectorint main(){ int num,i;

    cout > num;

    Vector v1(num);

    for (i= 0; i< num; i++)

    v1[i] = rand(); for (i= 0; i< num; i++) {

    cout

  • Curso 07-08 43

    Definid (.h) e implementad (.cpp) vuestra propia clase Vector deenteros con las siguientes caractersticas:

    Sobrecarga de operadores en C++Ejercicio: Clase Vector

    + Vector(int capacidad)+~Vector+Vector (const Vector &v)+operator=(const Vector&v): Vector&+operator==(const Vector &v): bool +operator!=(const Vector&v): bool +operator[](const int indice) const int& >//rvalue: debe controlar ndice fuera rango operator>>(Vector &v) operator

  • Curso 07-08 44

    Modifica lo que sea necesario en la declaracin y/o definicin deloperador asignacin para que controle los siguientes casos: (a=a) : debe dejar a intacto (a=b)=c (debe ser errneo).

    Si an no lo has hecho, redefine el constructor de copia en base a ladefinicin del operador =

    Modifica el cdigo asociado al operador [] para que pueda actuar delvalue en expresiones del tipo Vector v;v[3]=2;

    Sobrecarga de operadores en C++Ejercicio: Clase Vector

  • Curso 07-08 45

    Sobrecarga de operadores en C++Ejemplo: clase TTablaAsocObjetivo:

    Implementar una TablaAsociativa que contenga pares clave-valor (string-int), ypermitir el acceso mediante la clave al valor correspondienteE.g. int v=mitabla[clave]

    Ejemplo: Uso de una tabla Asociativa para guardar el nmero deveces que introduzco cada palabra

    int main(){

    char palabra[256];

    TTablaAsoc t(512);

    for (register int i=0;i>palabra;

    t[palabra]++;

    } cout

  • Curso 07-08 46

    Sobrecarga de operadores en C++Ejemplo: clase TTablaAsocstruct Tupla{ char * nombre; //por defecto visibilidad pblica int valor; };

    class TTablaAsoc { public: TTablaAsoc(int i); int& operator[] (const char* c); friend ostream& operator

  • Curso 07-08 47

    Sobrecarga de operadores en C++Ejemplo: clase TTablaAsocTTablaAsoc::TTablaAsoc(int i){ maxLong= (i

  • Curso 07-08 48

    Sobrecarga de operadores en C++Ejemplo: clase TTablaAsocint& TTablaAsoc::operator[] (const char* c){//devuelve una referencia al valor, creando antes la clave si es necesario register Tupla* ptaux; if (primeroLibre>0){ for (ptaux=&pt[primeroLibre-1];ptnombre)==0) return ptaux->valor; } //no se encontr la palabra en la tabla if (primeroLibre==maxLong){ Tupla* ptaux2=new Tupla[maxLong*2]; for (register int i=0;inombre=new char(strlen(c)+1); strcpy(ptaux->nombre,c); ptaux->valor=0; return ptaux->valor;};

  • Curso 07-08 49

    Alternativas a sobrecarga:Funciones con numero variable de argumentos

    Las funciones con nmero variable de argumentos(polidicas) se encuentran en distintos lenguajes P. ej. printf de C y C++

    Si el nmero mximo es conocido, en C++ y Delphy Pascalpodemos acudir a la definicin de valores por defecto paraparmetros opcionales P. ej. int sum (int e1, int e2, int e3=0, int e4=0);

    Respondera a sum (1,2), sum (1,2,3) y sum(1,2,3,4);

    Si el nmero mximo no es conocido, en C/C++ tenemosque acudir a la librera stdarg:#include int sum (int numEle, ...){ //... indica nm variable de args

    va_list ap; //tipos predefinidos en stdarg.hint resp=0;va_start(ap, numEle); //inicializa lista con el num argumentoswhile (numEle>0){

    resp += va_arg(ap,int);numEle--;

    }va_end(ap);return (resp);

    }

  • Curso 07-08 50

    Alternativas a sobrecarga:Coercin y Conversin

    En algunas ocasiones la sobrecarga puede sustituirse poruna operacin semnticamente diferente: La COERCIN Un valor de un tipo se convierte DE MANERA IMPLCITA en un valor

    de otro tipo distinto P.ej. Coercin implcita entre reales y enteros: su adicin puede ser

    interpretada al menos de tres formas distintas: Cuatro funciones distintas: integer+integer, integer+real,

    real+integer, real+real: slo sobrecarga Dos funciones distintas: integer+integer, real+real (si alguno es

    real, el otro se coerciona a real): coercin+sobrecarga Una sola funcin: real+real: slo hay coercin y no sobrecarga

    El principio de sustitucin en los LOO introduce adems una formade coercin que no se encuentra en los lenguajes convencionales

  • Curso 07-08 51

    Alternativas a sobrecarga:Coercin y Conversin Cuando el cambio en tipo es solicitado de manera explcita por el programador

    hablamos de CONVERSIN

    El operador utilizado para solicitad esta conversin se denomina CAST Ejemplo:

    float x; int i; x= i + x; // COERCION x= ((double) i) + x; // CONVERSION

    Un cast puede cambiar la representacin interna de la variable(convertir un entero en un real, p.ej.) o cambiar el tipo sin cambiar larepresentacin (p.ej., convertir un puntero a hijo en un puntero apadre).

    Dentro de una clase C podemos definir el cast: De un tipo externo al tipo definido por la clase: implementacin de

    constructor con un solo parmetro del tipo desde el cual queremosconvertir.

    Del tipo definido por la clase a otro tipo distinto en C++:implementacin de un operador de conversin.

  • Curso 07-08 52

    Alternativas a sobrecarga:Coercin y Conversin E.g. supongamos la siguiente clase:

    class Fraccion{public: Fraccion(int n,int d):num(n),den(d){};

    int numerador(){return num;};int denominador(){return den;};Fraccion operator*(Fraccion &dcha){};

    private: int num, den;};

    Para poder realizar la conversin:Fraccin f=(Fraccion) 3;//pasar de entero a fraccin

    Sera necesario aadir a la clase fraccin el constructor:Fraccin (int i) {num=i;den=1;};

    Esto a su vez permitira operaciones comoFraccin f(2,3),f2; //dos terciosf2=f*3; // dara 6/3

  • Curso 07-08 53

    Alternativas a sobrecarga:Coercin y Conversin Si adems deseamos realizar la conversin:

    double d=f*3.14;

    Sera necesario aadir a la clase fraccin el operador:operator double() { //SIN TIPO RETORNOreturn (numerador()/(double)denominador());

    };

    Obviamente, cuando la coercin (conversin implcita), laconversin (explcita) y la sustitucin de valores secombinan en una sola sentencia, el algoritmo que debeutilizar el compilador para resolver una funcinsobrecargada puede convertirse en bastante complejo.

  • Curso 07-08 54

    Indice1. Motivacin y conceptos previos

    Signatura y mbito Tiempo de enlace

    2. Polimorfismo y reutilizacin Definicin Tipos de polimorfismo

    3. Sobrecarga Sobrecarga basada en mbito Sobrecarga basada en signatura de tipo Alternativas a la sobrecarga

    4. Polimorfismo en jerarquas de herencia Redefinicin Shadowing Sobrescritura

    5. Variables polimrficas La variable receptora Downcasting Polimorfismo puro

    6. Genericidad Funciones genricas en C++ Plantillas de clase en C++ Herencia en clases genricas

  • Curso 07-08 55

    Polimorfismo en jerarquas de herenciaSobrecarga en jerarquas de herencia

    Mtodos con el mismo nombre, la misma signatura de tipo yenlace esttico: Shadowing (refinamiento/reemplazo): las signaturas de tipo

    son las misma en clases padre e hijas, pero el mtodo a invocar sedecide en tiempo de compilacin

    En C++ implica que el mtodo no se declar como virtual en clasepadre.

    Mtodos con el mismo nombre y distinta signatura de tipo yenlace esttico: Redefinicin: clase hija define un mtodo con el mismo nombre

    que el padre pero con distinta signatura de tipos. Modelo MERGE: SOBRECARGA Modelo JERRQUICO: NO HAY SOBRECARGA

  • Curso 07-08 56

    Polimorfismo en jerarquas de herenciaSobrecarga en jerarquas de herencia Dos formas de resolver la redefinicin en LOO:

    Modelo merge (Java): Los diferentes significados que se encuentran en todos los mbitos actualmente

    activos se unen para formar una sola coleccin de mtodos. Modelo jerrquico (C++):

    Cuando se encuentra un mbito en el que el nombre est definido, lacoincidencia ms cerbcana en ese mbito ser la seleccionada para resolver lallamada.

    class Padre{public: void ejemplo(int a){cout

  • Curso 07-08 57

    Polimorfismo en jerarquas de herenciaSobreescritura (Overriding, polimorfismo de inclusin)

    Decimos que un mtodo en una clase derivada sobreescribe un mtodo en laclase base si los dos mtodos tienen el mismo nombre, la misma signatura detipos y enlace dinmico. Un mismo nombre de mensaje asociado a varias implementaciones (como la

    sobrecarga) PERO: en clases relacionadas mediante jerarquas de herencia La signatura de tipos debe ser EXACTAMENTE la misma Los mtodos sobreescritos pueden suponer un reemplazo del comportamiento (mtodo

    independiente del del padre, igual que la sobrecarga) o un refinamiento (mtodo noindependiente)

    La resolucin del mtodo a invocar se produce en tiempo de ejecucin (enlace dinmico olate-binding) en funcin del tipo dinmico del receptor del mensaje.

    El tipo de cualquier otro argumento pasado junto con el mensaje sobreescritogeneralmente no juega ningn papel en el mecanismo de seleccin del mtodosobreescrito.

    La sobreescritura es importante cuando se combina con el ppio. de sustitucin. Una variable del tipo del padre puede, por el principio de sustitucin, ser declarada

    como de tipo Padre pero contener en realidad un valor del tipo hijo. Cuando unmensaje que se corresponde con un mtodo sobreescrito se pasa a dicha variable, elmtodo que ser ejecutado es el proporcionado por el hijo, NO por el padre.

  • Curso 07-08 58

    Polimorfismo en jerarquas de herenciaSobreescritura

    En algunos lenguajes (Java, Smalltalk) la simple existencia de unmtodo con el mismo nombre y signatura de tipos en clase base yderivada indica sobreescritura.

    En otros lenguajes (Object Pascal), la clase derivada debe indicar quesobreescribe un mtodo.

    Otros lenguajes (C#, Delphi Pascal) exigen que tanto la clase basecomo la derivada lo indiquen.

    En C++ es la clase base la que debe indicar explcitamente que unmtodo puede ser sobreescrito (aunque dicha marca no obliga a que losea) Palabra reservada virtual.

    class Padre{public: virtual int ejemplo(int a){cout

  • Curso 07-08 59

    Polimorfismo en jerarquas de herenciaSobreescritura y mtodos diferidos (virtuales puros o abstractos)

    En los lenguajes fuertemente tipados, si queremos sobreescribir un mtodo enlas clases hijas para poder invocarlo mediante una variable polimrfica, esnecesario que dicho mtodo est definido en la clase padre. No obstante, esposible que dicha clase padre no pueda definir ningn comportamiento porcarecer de la informacin necesaria.

    Solucin: mtodos diferidos o abstractos C++: virtual puro

    class Forma{public: virtual void dibujar()=0;

    //mec. abstraccin: asocia el concepto dibujar() con la clase //Forma y no con cada una de las hijas

    };class Circulo: public Forma{

    public: void dibujar(){...}

    };

    Los mtodos virtuales puros (de sobreescritura necesaria, y que implementan laespecializacin) a menudo conviven con mtodos no sobreescribibles, base delreuso de cdigo.

  • Curso 07-08 60

    PolimorfismoSobreescritura, Shadowing y Redefinicin

    Es importante distinguir entre Sobreescritura,Shadowing y Redefinicin (vistos en Sobrecarga)

    Sobreescritura: la signatura de tipo para el mensaje esla misma en clase base y derivada, pero el mtodo seenlaza con la llamada en tiempo de ejecucin (en C++ elmtodo se declara como virtual en la clase padre).

    Shadowing: la signatura de tipo para el mensaje es lamisma en clase base y derivada, pero el mtodo seenlaza en tiempo de compilacin (en funcin del tipo dela variable receptora).

    Redefinicin: La clase derivada define un mtodo conel mismo nombre que en la calse base y con distintasignatura de tipos.

  • Curso 07-08 61

    Indice1. Motivacin y conceptos previos

    Signatura y mbito Tiempo de enlace

    2. Polimorfismo y reutilizacin Definicin Tipos de polimorfismo

    3. Sobrecarga Sobrecarga basada en mbito Sobrecarga basada en signatura de tipo Alternativas a la sobrecarga

    4. Polimorfismo en jerarquas de herencia Redefinicin Shadowing Sobrescritura

    5. Variables polimrficas La variable receptora Downcasting Polimorfismo puro

    6. Genericidad Funciones genricas en C++ Plantillas de clase en C++ Herencia en clases genricas

  • Curso 07-08 62

    Variables Polimrficas (Polimorfismo de asignacin)

    Una variable polimrfica es aqulla quepuede referenciar ms de un tipo de objeto Puede mantener valores de distintos tipos en distintos

    momentos de ejecucin del programa.

    En un lenguaje dbilmente tipado todas lasvariables son potencialmente polimrficas

    En un lenguaje fuertemente tipado lavariable polimrfica es la materializacin delprincipio de sustitucin.

  • Curso 07-08 63

    Variables Polimrficas. Tipos

    Variables polimrficas simples Barco *b[10]; //array de punteros a Barco que en realidad

    //contiene punteros a las distintas clases derivadas

    Variable polimrfica como receptor de mensaje this: en cada clase representa un objeto de un tipo distinto. Especialmente potente cuando se combina con sobreescritura.

    class Barco{public:virtual int getNumPiezas()=0;void colocaPieza(Pieza &p, Coordenada);bool colocaBarco(){ Coordenada caleatoria; Direccion daleatoria; for (int x=0;xgetNumPiezas();x++){ // this apunta a objetos de clase derivada colocaPieza(piezas[x],caleat); caleat.incrementa(daleat); }

    } private: Pieza piezas[MAX_PIEZAS];

    }

  • Curso 07-08 64

    Variables Polimrficas. Tipos

    Downcasting (polimorfismo inverso): Proceso de deshacer el ppio. de sustitucin. Puede dar

    problemas. En C++:

    Child *c=dynamic_cast(aParentptr);if (c!=0) {//nulo si no es legal, no nulo si OK}

    Variable polimrfica utilizada como argumento de unmtodo: polimorfismo puro o mtodo polimrfico.

    Un solo mtodo puede ser utilizado con un nmeropotencialmente ilimitado de tipos distintos de argumento.

  • Curso 07-08 65

    Variables Polimrficas. Polimorfismo puro

    Ejemplo de polimorfismo puro

    class Aplicacion(){public: int getNumBarcosAplicacion(){ return numSub+numAcor+numDest+numPort;}bool crearColocarBarcos(){

    b=new Barco*[numBarcos];for (int x=0;x

  • Curso 07-08 66

    Ejemplo: Uso de polimorfismo y jerarqua de tipos

    +getDatos() : String

    -nombre

    Persona

    +getDatos() : String

    +getEmpresa() : String

    -empresa

    Empleado

    +getDatos() : String

    +getCarrera() : String

    -carrera

    Estudiante

  • Curso 07-08 67

    Ejemplo: Uso de polimorfismo y jerarqua de tipos

    class Persona { public:

    Persona(string n) {nombre=n;};

    ~Persona();

    string getDatos() {return (nombre);}; ... private:

    string nombre;

    };

  • Curso 07-08 68

    Ejemplo: Uso de polimorfismo y jerarqua de tipos

    class Empleado: public Persona { public: Empleado(string n,string e): Persona(n){empresa=e;}; ~Empleado(){}; string getDatos(){

    return Persona::getDatos()+trabaja en " + empresa);};

    ... private:

    string empresa;};class Estudiante: public Persona { public: Estudiante(string n,string c): Persona (n){carrera=c;};

    ~Estudiante(){}; string getDatos(){

    return(Persona::getDatos() + " estudia " + carrera); }; ... private:

    string carrera;};

    Refinamiento

    Refinamiento

  • Curso 07-08 69

    Ejemplo: Uso de polimorfismo y jerarqua de tipos

    int main(){

    Empleado empleadoDesc(Carlos,Lavandera); Persona pers(Juan); empleadoDesc=pers; cout

  • Curso 07-08 70

    Ejemplo: Uso de polimorfismo y jerarqua de tipos

    int main(){ int i; Empleado *empleadoDesc=NULL; Estudiante *estudianteDesc= NULL; Persona *pers=new Persona(Jos); empleadoDesc=pers; estudianteDesc=pers; cout

  • Curso 07-08 71

    Ejemplo: Uso de polimorfismo y jerarqua de tipos

    int main(){Empleado uno("Carlos", "lavanderia");

    Estudiante dos("Juan", "empresariales"); Persona desc("desconocida");desc=uno; //le asigno empleado

    cout

  • Curso 07-08 72

    Ejemplo: Uso de polimorfismo y jerarqua de tipos

    int main(){ Empleado *emp= new Empleado("Carlos",

    "lavanderia"); Estudiante *est= new Estudiante("Juan",

    "empresariales"); Persona *pers; pers = emp; cout

  • Curso 07-08 73

    Ejemplo: Uso de polimorfismo y jerarqua de tipos

    class Persona { public:

    Persona(string n) {nombre=n;};

    ~Persona();

    virtual string getDatos() {return (nombre);

    }; ... private:

    string nombre;

    };

    Puede ser resueltodinmicamente

  • Curso 07-08 74

    Ejemplo: Uso de polimorfismo y jerarqua de tipos

    int main(){ Empleado uno("Carlos", "lavanderia"); Estudiante dos("Juan", "empresariales"); Persona desc("desconocida"); desc=uno; //un empleado es una persona cout

  • Curso 07-08 75

    Ejemplo: Uso de polimorfismo y jerarqua de tipos

    int main(){ Empleado *uno= new Empleado("Carlos", "lavanderia"); Estudiante *dos= new Estudiante("Juan",

    "empresariales"); Persona *desc; desc = uno; cout getDatos()

  • Curso 07-08 76

    Ejemplo: Uso de polimorfismo y jerarqua de tipos

    int main1(){ Empleado *uno= new Empleado("Carlos", "lavanderia"); Persona *desc = uno; cout getEmpresa()

  • Curso 07-08 77

    PolimorfismoConsecuencias para la definicin de destructores en jerarquasint main(){ Empleado *uno= new Empleado("Carlos", "lavanderia"); Estudiante *dos= new Estudiante("Juan",

    "empresariales"); Persona *desc; desc = uno; cout

  • Curso 07-08 78

    PolimorfismoImplementacin interna en C++ Las funciones virtuales son algo menos eficientes que las funciones

    normales. Cada clase con funciones virtuales dispone de un vector de punteros

    llamado v_table. Cada puntero corresponde a una funcin virtual, y apuntaa su implementacin ms conveniente (la de la propia clase o, en caso deno existir, la del ancestro ms cercano que la tenga definida)

    Cada objeto de la clase tiene un puntero oculto a esa v_table.

  • Curso 07-08 79

    PolimorfismoVentajas El polimorfismo hace posible que un usuario pueda aadir nuevas clases a

    una jerarqua sin modificar o recompilar el cdigo original.

    Estableces clase base Defines nuevas variables y funciones Ensamblas con el cdigo objeto que tenas Los mtodos de la clase base pueden ser reutilizados con variables y parmetros

    de la clase derivada. Permite programar a nivel de clase base utilizando objetos de clases derivadas

    (posiblemente no definidas an): Tcnica base de las libreras/frameworks

  • Curso 07-08 80

    RepasoUso de virtual en C++ Resolucin de conflictos en herencia mltiple Especificacin de posibilidad de enlazado dinmico

    Necesario (funciones virtuales puras) Posible (funciones virtuales donde existe refinamiento/reemplazo en las

    clases hijas)

  • Curso 07-08 81

    Indice1. Motivacin y conceptos previos

    Signatura y mbito Tiempo de enlace

    2. Polimorfismo y reutilizacin Definicin Tipos de polimorfismo

    3. Sobrecarga Sobrecarga basada en mbito Sobrecarga basada en signatura de tipo Alternativas a la sobrecarga

    4. Polimorfismo en jerarquas de herencia Redefinicin Shadowing Sobrescritura

    5. Variables polimrficas La variable receptora Downcasting Polimorfismo puro

    6. Genericidad Funciones genricas en C++ Plantillas de clase en C++ Herencia en clases genricas

  • Curso 07-08 82

    GenericidadMotivacin

    La genericidad es otro tipo de polimorfismo Para ilustrar la idea de la genericidad se propone un ejemplo:

    Suponed que queremos implementar una funcin mximo, donde losparmetros pueden ser de distinto tipo (int, double, float)Qu harais?

  • Curso 07-08 83

    GenericidadMotivacin

    Solucin:

    double maximo(double a, double b){ if (a > b) return a; else return b;};int main (void){ int y,z;

    float b,c;double t,u;double s= maximo(t,u);double a= maximo((double)b,(double)c);double x= maximo((double)y,(double)z);

    }

  • Curso 07-08 84

    GenericidadMotivacin

    Ahora suponed que creamos una clase TCuenta, y tambinqueremos poder compararlas con la funcin maximo().

  • Curso 07-08 85

    GenericidadMotivacin

    1 Sobrecargar el operador > para TCuenta2 Sobrecargar la funcin mximo para TCuenta

    TCuenta maximo(TCuenta a, TCuenta b){ if (a>b) return a; else return b;}void main (void){

    double s,t,u;TCuenta T1,T2,T3;s= maximo(t,u);T1= maximo(T2,T3);

    }Conclusin: Tenemos dos funciones mximo definidas, una para double y

    otra para TCuenta, pero el cdigo es el mismo. La nica diferencia son losparmetros de la funcin y el valor devuelto por sta.

  • Curso 07-08 86

    GenericidadMotivacin

    Y si no sabemos a priori los tipos que otros van a crear para sercomparados? Necesitaramos una funcin genrica que nos sirviera para cualquier

    tipo sin necesidad de tener la funcin duplicada.

  • Curso 07-08 87

    GenericidadDEFINICION

    Propiedad que permite definir una clase o una funcin sin tener queespecificar el tipo de todos o algunos de sus miembros oargumentos.

    Su utilidad principal es la de agrupar variables cuyo tipo base noest predeterminado (p. ej., listas, colas, pilas etc. de objetosgenricos).

    Es el usuario el que indica el tipo de la variable cuando crea unobjeto de esa clase.

    En C++ esta caracterstica apareci a finales de los 80.

  • Curso 07-08 88

    Genericidad en C++:Templates

    Utilizan la palabra clave template (plantilla) Dos tipos de plantillas:

    Plantillas de funciones: son tiles para implementar funciones queaceptan argumentos de tipo arbitrario.

    Plantillas de clase: su utilidad principal consiste en agrupar variablescuyo tipo no est predeterminado (clases contenedoras)

  • Curso 07-08 89

    GenericidadEjemplo de Funcin con argumentos genricos

    template T maximo(T a, T b){ if (a > b) return a; else return b;};

    int main (void){

    TCuenta a,b,c;int x,y,z;z= maximo(x,y); //OKc= maximo(a,y); //INCORRECTOc= maximo(a,b); //?}

    Qu tendra que hacer para, aplicando la funcinmximo, poder obtener la cuenta con ms saldo?

    Un argumento genrico

  • Curso 07-08 90

    GenericidadEjemplo de Funcin con argumentos genricos

    template T1 sumar (T1 a, T2 b){

    return (a+b);};

    int main (void){

    int euno=1; int edos=2; char cuno='a'; char cdos='d'; cout

  • Curso 07-08 91

    GenericidadSobrecarga de funciones genricas

    La sobrecarga de las funciones genricas es igual a la de lasfunciones normales.

    template T min(T a, T b){} //OK

    template T min(int a, T b){} //OK

    template T min(int a, int b){} //OK, pero intil

    // pero

    int main() { int a,b,c; c=min(a,b) //?}

  • Curso 07-08 92

    GenericidadClases genricas en C++

    Utilizan la palabra clave template Dos tipos de plantillas:

    Plantillas de funciones: son tiles para implementar funcionesque aceptan argumentos de tipo arbitrario.

    Plantillas de clase: su utilidad principal consiste en agruparvariables cuyo tipo no est predeterminado

  • Curso 07-08 93

    GenericidadEjemplo Clase Genrica

    A continuacin se plantea un ejemplo de una clase genricavector, este vector va a contener elementos de tipo genrico,no se conocen a priori.

  • Curso 07-08 94

    GenericidadEjemplo Clase Genrica

    template class vector { private: T *v;

    int tam; public: vector(int);

    T& operator[](int);};void main (void){ vector vi(10); vector vf(20); vector vd(50);}

  • Curso 07-08 95

    GenericidadEjemplo Mtodos de una Clase Genrica

    template vector::vector(int size) {tam=size;v=new T[size];

    };

    template T& vector::operator[](int i) {return(v[i]);

    };

  • Curso 07-08 96

    GenericidadEjemplo de uso de una Clase Genrica

    Creacin del objeto:

    vector d(30);

    vector *p=new vector(50);

  • Curso 07-08 97

    GenericidadEjemplo: Pila de Objetos Genrica

    El siguiente ejemplo es una pila que contendr objetos decualquier tipo, para ello la vamos a definir como una clasegenrica o plantilla. En esta pila podremos introducir nuevoselementos e imprimir el contenido de la misma.

  • Curso 07-08 98

    GenericidadEjemplo: Pila de Objetos Genrica

    template class Pila{ public: Pila(int nelem=10); void apilar (T); void imprimir(); ~Pila();

    private: int nelementos; T* info; int cima; static const int limite=30;};

  • Curso 07-08 99

    GenericidadEjemplo: Pila de Objetos Genrica

    template Pila::Pila(int nelem){ if (nelem

  • Curso 07-08 100

    GenericidadEjemplo: Pila de Objetos Genrica

    template void Pila::apilar(T elem){ if (cima

  • Curso 07-08 101

    GenericidadEjemplo: Pila de Objetos Genrica#include TPila.h"#include "TCuenta.h"

    int main(){

    Pila pCuentas(6); TCuenta c1("Cristina",20000,5); TCuenta c2("Antonio",10000,3); pCuentas.apilar(c1); pCuentas.apilar(c2); pCuentas.imprimir();

    Pila pchar(8); pchar.apilar('a'); pchar.apilar('b'); pchar.imprimir();} //end main

    De manera anloga, plantead una lista de objetos genrica.

  • Curso 07-08 102

    GenericidadHerencia en clases genricas

    Se pueden derivar clases genricas de otras clases genricas:

    Clase base genrica:

    template class Pila{

    public:void poner(T a):

    private:T* buffer;int cabeza;

    };

  • Curso 07-08 103

    GenericidadHerencia en clases genricas

    Clase derivada genrica:

    template class doblePila: public Pila{

    public:void poner2(T a);

    };

  • Curso 07-08 104

    GenericidadHerencia en clases genricas

    Se pueden derivar una clase no genrica deuna genrica

    Clase base genrica:

    template class Pila{

    public:void poner(T a):

    private:T* buffer;int cabeza;

    };

  • Curso 07-08 105

    GenericidadHerencia en clases genricas

    Clase derivada no genrica:

    class monton: public Pila{

    public:void poner2(int a);

    };

    En C++, no existe relacin alguna entre dos clases generadasdesde la misma clase genrica.

  • Curso 07-08 106

    GenericidadConstantes en plantillas

    Los argumentos de una plantilla no estn restringidos a serclases definidas por el usuario, tambin pueden ser tipos dedatos existentes.

    Los valores de estos argumentos se convierten en constantes entiempo de compilacin para una instanciacin particular deltemplate.

    Tambin se pueden usar valores por defecto para estosargumentos.

  • Curso 07-08 107

    GenericidadEjemplo Constantes en plantillas

    template class Array{

    public:T& operator[](int index) ;int length() const { return size; }private:

    T array[size];};int main(){

    Array t; int i=10; Array t2; // ERROR, no constante.}

  • Curso 07-08 108

    PolimorfismoResumen

    Con las funciones virtual y el polimorfismo es posible disear eimplementar sistemas que sean ms fcilmente extensibles. Es posibleescribir programas para que procesen objetos de tipos que tal vez noexistan cuando el programa est bajo desarrollo.

    La programacin polimrfica con funciones virtual puede eliminar lanecesidad de lgica de switch. El programador puede utilizar elmecanismo de funcin virtual para realizar automticamente lalgica equivalente, evitando de esta forma los tipos de erroresasociados con la lgica de switch. El cdigo cliente que tomadecisiones acerca de tipos de objetos y representaciones es seal deun pobre diseo de clases.

    Las clases derivadas pueden proporcionar su propia implementacinde una funcin virtual de clase base, en caso de ser necesario,pero si no lo hacen se utiliza la implementacin de la clase base.

    Si se invoca una funcin virtual haciendo referencia a un objetoespecfico por nombre y utilizando el operador punto de seleccin demiembros, la referencia se resuelve en tiempo de compilacin (a estose le llama enlace esttico), y la funcin virtual que se llama esaqulla definida para (o heredada por) la clase de ese objeto particular.

  • Curso 07-08 109

    PolimorfismoResumen

    Hay muchas situaciones en las cuales es til definir clases para lascuales el programador nunca pretende instanciar ningn objeto. A talesclases se les llama clases abstractas. Debido a que slo se utilizancomo clases base, normalmente las mencionaremos como clases baseabstractas. No es posible instanciar en un programa ningn objeto deuna clase abstracta.

    Las clases de las que se pueden instanciar objetos son llamadasclases concretas.

    Una clase se hace abstracta mediante la declaracin de que una oms de sus funciones virtual sean puras. Una funcin virtualpura es aqulla que tiene un inicializador de = 0 en su declaracin.

    Si una clase se deriva de una clase que tiene funciones virtualpuras sin proporcionar una definicin para esa funcin virtual puraen la clase derivada, dicha funcin sigue siendo pura en la clasederivada. Por consecuencia, la clase derivada tambin es una claseabstracta (y no puede tener ningn objeto).

    C++ permite el polimorfismo la habilidad de que objetos dediferentes clases relacionados por herencia respondan en formadiferente a la misma llamada de funcin miembro.

  • Curso 07-08 110

    PolimorfismoResumen

    El polimorfismo se implementa por medio de funciones virtual. Cuando se hace una peticin, por medio de un apuntador o referencia

    a clase base, para que se utilice una funcin virtual, C++ elige lafuncin sobrepuesta correcta en la clase derivada adecuada que estasociada con el objeto.

    Mediante el uso de funciones virtual y el polimorfismo una llamadade funcin miembro puede causar diferentes acciones, dependiendodel tipo del objeto que recibe la llamada.

    Aunque no podemos instanciar objetos de clases base abstractas, spodemos declarar apuntadores hacia clases base abstractas. Talesapuntadores pueden utilizarse para permitir manejos polimrficos deobjetos de clases derivadas cuando tales objetos se instancian a partirde clases concretas.

    Regularmente se agregan nuevos tipos de clases a los sistemas. Lasnuevas clases son amoldadas mediante el enlace dinmico (tambinllamado enlace tardo). No es necesario saber el tipo de un objeto entiempo de compilacin para que se pueda compilar una llamada defuncin virtual. En tiempo de ejecucin la llamada de funcinvirtual se hace coincidir con la funcin miembro del objeto que larecibe.

  • Curso 07-08 111

    PolimorfismoResumen

    El enlace dinmico permite que los ISV distribuyan software sin revelar sussecretos propios. Las distribuciones de software pueden consistir solamente dearchivos de encabezado y archivos objeto. No es necesario revelar nada delcdigo fuente. Los desarrolladores de software despus pueden utilizar laherencia para derivar nuevas clases a partir de las que proporcionan los ISV. Elsoftware que funciona con las clases que proporcionan los ISV continuarfuncionando con las clases derivadas y utilizar (por medio de enlace dinmico)las funciones virtual sobrepuestas que se proporcionan en esas clases.

    El enlace dinmico requiere que en tiempo de ejecucin la llamada a unafuncin miembro virtual sea dirigida hacia la versin de la funcin virtualadecuada para esa clase. Una tabla de funciones virtuales, llamada vtable,est implementada como un arreglo que contiene apuntadores de funcin. Cadaclase que contiene funciones virtual tiene una vtable. Para cada funcinvirtual de la clase, la vtable tiene una entrada que contiene un apuntador afuncin hacia la versin de la funcin virtual que hay que utilizar para unobjeto de esa clase. La funcin virtual que hay que utilizar para una claseparticular podra ser la funcin definida en esa clase, o una funcin heredadadirecta o indirectamente de una clase base que est en un nivel ms elevado enla jerarqua.

  • Curso 07-08 112

    PolimorfismoResumen

    Cuando una clase base proporciona una funcin miembro virtual, las clasesderivadas pueden sobreponer a la funcin virtual pero no estn obligadas ahacerlo. Por lo tanto, una clase derivada puede utilizar la versin de la clasebase de la funcin miembro virtual, y esto estara indicado en la vtable.

    Cada objeto de una clase que tiene funciones virtual contiene un apuntadorhacia la vtable de esa clase. El apuntador a funcin adecuado en la vtable seobtiene y desreferencia para completar la llamada en tiempo de ejecucin. Estabsqueda en la vtable y la desreferenciacin del apuntador requieren unasobrecarga nfima del tiempo de ejecucin, que por lo general es menor que elmejor cdigo cliente posible.

    Declare como virtual al destructor de la clase base si la clase contienefunciones virtual. Esto hace que todos los destructores de las clasesderivadas sean virtual aunque no tengan el mismo nombre que el destructorde la clase base. Si un objeto de la jerarqua es destruido explcitamente pormedio de la aplicacin del operador delete al apuntador de clase base a unobjeto de clase derivada, se invoca el destructor de la clase adecuada.

    Cualquier clase que tenga uno o ms apuntadores 0 en su vtable es una claseabstracta. Las clases que no tengan un apuntador a vtable que sea 0 (comoPoint, Circle y Cylinder) son clases concretas.

  • Curso 07-08 113

    Tema 4. PolimorfismoBibliografa

    Cachero et. al. Introduccin a la programacin orientada a Objetos

    Captulo 4

    T. Budd. An Introduction to Object-oriented Programming, 3rd ed.

    Cap. 11,12,14-18; cap. 9: caso de estudio en C#

    Scott Meyers Effective C++. Third Edition

    Cap. 6 y 7: Algunas secciones sobre polimorfismo en herencia ygenericidad