PDF de programación - Polimorfismo y Funciones Virtuales

Imágen de pdf Polimorfismo y Funciones Virtuales

Polimorfismo y Funciones Virtualesgráfica de visualizaciones

Publicado el 31 de Mayo del 2019
466 visualizaciones desde el 31 de Mayo del 2019
25,5 KB
21 paginas
Creado hace 22a (29/08/2001)
Polimorfismo y Funciones
y Funciones
Polimorfismo

Virtuales
Virtuales

Agustín J. González

Versión original de Kip Irvine

ELO326: Seminario II

2do. Sem 2001

1

Jerarquía de clases Motor
Jerarquía de clases Motor

Consideremos la jerarquía de clases
establecida en la sesión sobre Herencia:

Motor

ElectricMotor

GasMotor

Clase CMotor
CMotor
Clase

La definición de la clase CMotor:

class CMotor {
public:
CMotor() { }
CMotor( const string & id );

string get_ID() const;

void set_ID(const string & s);

void Display() const;
void Input();

private:

string m_sID;

};

Clase CElectricMotor
CElectricMotor
Clase

class CElectricMotor : public CMotor {
public:
CElectricMotor();
CElectricMotor(const string & id,
double volts);

void Display() const;

void Input();
void set_Voltage(double volts);
double get_Voltage() const;

private:

double m_nVoltage;

};

Clase CGasMotor
CGasMotor
Clase

class CGasMotor :public CMotor {
public:
CGasMotor();

CGasMotor(const string & id, int cylinders);

void Display() const;

void Input();

private:
int m_nCylinders;
};

Punteros a objetos de clases
Punteros a objetos de clases

derivadas
derivadas

Es fácil definir objetos dinámicos de una clase
derivada usando un puntero de tipo específico:

CElectricMotor * pC = new CElectricMotor;

pC->set_ID("3099999");
pC->set_Voltage(110.5);
pC->Display();

delete pC;

Polimorfismo
Polimorfismo

También podemos declarar punteros a una clase
base, y luego asignarle la dirección de un objeto de
una clase derivada. Esta técnica es llamada
polimorfismo.
Polimorfismo es un concepto donde un mismo
nombre puede denotar objetos de clases diferentes
que están relacionadas por una clase base común.

CMotor * pM;
pM = new CElectricMotor;

Este tipo de asignación es llamada “ligado” dinámico
“dynamic binding” porque el tipo exacto asignado al
puntero es desconocido hasta el momento de la
ejecución.

Problema de ligado dinámico
Problema de ligado dinámico

Sin embargo, hay un pequeño problema cuando
usamos ligado dinámico. Si no somos cuidadosos, el
compilador C++ puede llamar las funciones Input and
Display de las clase CMotor:

CMotor * pM; // base pointer type
pM = new CElectricMotor;

pM->Input(); // calls CMotor::Input()
pM->Display(); // calls CMotor::Display()

// more...

Funciones Virtuales (Virtual)
Funciones Virtuales (Virtual)

La solución al problema de la trasparencia previa es fácil
de solucionar declarando las funciones Input and Display
como virtuales.
El calificativo virtual le dice al compilador que genere
código que mire al tipo del objeto en tiempo de ejecución y
use esta información para seleccionar la versión apropiada
de la función.

class CMotor {
...

virtual void Display() const;

virtual void Input();

...
};

Funciones Virtuales
Funciones Virtuales

Es recomendable definir también como virtuales las
funciones en la clase derivada, en las clases
CGasMotor y CElectricMotor en este caso.

class CGasMotor :public CMotor {
public:
...
virtual void Display() const;

virtual void Input();

...
};

Funciones Virtuales
Funciones Virtuales

Ahora las funciones Display e Input son
correctamente llamadas desde la clase
CElectricMotor:

CMotor * pM;
pM = new CElectricMotor;

pM->Input(); // CElectricMotor::Input()
pM->Display(); // CElectricMotor::Display()

Funciones Virtuales
Funciones Virtuales

A menudo, un puntero será pasado a una función
que pide un puntero a la clase base. Cuando la
función es llamada, podemos pasar cualquier puntero
como parámetro actual, siempre y cuando este sea
derivado de la clase base.

void GetAndShowMotor( CMotor * pC )
{
pC->Input();
cout << "\nHere's what you entered:\n";
pC->Display();
cout << "\n\n";
}

Funciones Virtuales
Funciones Virtuales

Ejemplo de llamados a GetAndShowMotor con
diferentes tipos de punteros.

CGasMotor * pG = new CGasMotor;
GetAndShowMotor( pG );

CElectricMotor * pE = new CElectricMotor;
GetAndShowMotor( pE );

CMotor * pM = new CGasMotor;
GetAndShowMotor( pM );

// view output...

(Salida de la diapositiva previa)

[GasMotor]: Enter the Motor ID: 234323
Enter the number of cylinders: 3

Here's what you entered:
[GasMotor] ID=234323, Cylinders=3

[ElectricMotor]: Enter the Motor ID: 234324
Voltage: 220

Here's what you entered:
[ElectricMotor] ID=234324, Voltage=220

[GasMotor]: Enter the Motor ID: 44444
Enter the number of cylinders: 5

Here's what you entered:
[GasMotor] ID=44444, Cylinders=5

Creación de un vector de Motores
Creación de un vector de Motores

Un vector de punteros CMotor puede contener
punteros a cualquiera tipo de objeto derivado de
CMotor.

vector<CMotor*> vMotors;
CMotor * pMotor;

pMotor = new CElectricMotor("10000",110);
vMotors.push_back(pMotor);

pMotor = new CGasMotor("20000",4);
vMotors.push_back(pMotor);

pMotor = new CElectricMotor("30000",220);
vMotors.push_back(pMotor);

pMotor = new CGasMotor("40000",2);
vMotors.push_back(pMotor);

Despliegue de Vectores
Despliegue de Vectores

La función que despliega tales vectores no necesita
saber exactamente qué tipo de puntero están en el
vector mientras se llame a funciones virtuales.

void ShowVector( const vector<CMotor*> & vMotors )
{
cout << "---- Vector of Motor Pointers ----\n";
for(int i=0; i < vMotors.size(); i++)
{
cout << (i+1) << ": ";
vMotors[i]->Display(); // virtual
}
}

Salida de la función ShowVector
ShowVector
Salida de la función

La función ShowVector llama a la versión apropiada
de la función virtula Display() para cada puntero en el
vector.

------- Vector of Motor Pointers -------
1: [ElectricMotor] ID=10000, Voltage=110
2: [GasMotor] ID=20000, Cylinders=4
3: [ElectricMotor] ID=30000, Voltage=220
4: [GasMotor] ID=40000, Cylinders=2

Liberación de almacenamiento
Liberación de almacenamiento

Debemos liberar el almacenamiento usado por cada
objeto motor. Este bucle remueve los punteros uno
por uno.

for(int i=0; i < vMotors.size(); i++)
{

delete vMotors[i]; // delete each motor

}

El operador delete acede a información que le
permite saber exactamente cuanto almacenamiento
liberar por cada puntero (aun cuando los motores
ocupan distintos tamaños).

Funciones Virtuales Puras
Funciones Virtuales Puras

Una función virtual pura no tiene implementación.
Esto es identificado con un "= 0" al final de la
declaración.
Una función virtual pura requiere que la función sea
implementada en la clase derivada.

class CMotor {
public:
//...

virtual void Display() const = 0;

virtual void Input() = 0;

//...

Clases Abstractas (Abstract Classes
Abstract Classes))
Clases Abstractas (

Una clase que contiene una o más funciones
virtuales puras es llamada clase abstracta. NO es
posible crear instancias de una clase abstracta.

CMotor M;

// error

CMotor * pM = new CMotor; // error

FinFin

21
  • Links de descarga
http://lwp-l.com/pdf16008

Comentarios de: Polimorfismo y Funciones Virtuales (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios...
CerrarCerrar
CerrarCerrar
Cerrar

Tienes que ser un usuario registrado para poder insertar imágenes, archivos y/o videos.

Puedes registrarte o validarte desde aquí.

Codigo
Negrita
Subrayado
Tachado
Cursiva
Insertar enlace
Imagen externa
Emoticon
Tabular
Centrar
Titulo
Linea
Disminuir
Aumentar
Vista preliminar
sonreir
dientes
lengua
guiño
enfadado
confundido
llorar
avergonzado
sorprendido
triste
sol
estrella
jarra
camara
taza de cafe
email
beso
bombilla
amor
mal
bien
Es necesario revisar y aceptar las políticas de privacidad