Pensar en C++ (Volumen 1) - Grupo ARCO
Pensar en C++ (Volumen 1) - Grupo ARCO
Pensar en C++ (Volumen 1) - Grupo ARCO
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
✐<br />
✐<br />
✐<br />
“Volum<strong>en</strong>1” — 2012/1/12 — 13:52 — page 458 — #496<br />
✐<br />
Capítulo 15. Polimorfismo y Funciones virtuales<br />
Derived1 d1;<br />
int x = d1.f();<br />
d1.f(s);<br />
Derived2 d2;<br />
x = d2.f();<br />
//! d2.f(s); // string version hidd<strong>en</strong><br />
Derived4 d4;<br />
x = d4.f(1);<br />
//! x = d4.f(); // f() version hidd<strong>en</strong><br />
//! d4.f(s); // string version hidd<strong>en</strong><br />
Base& br = d4; // Upcast<br />
//! br.f(1); // Derived version unavailable<br />
br.f(); // Base version available<br />
br.f(s); // Base version abailable<br />
} ///:~<br />
La primera cosa a resaltar es que <strong>en</strong> Derived3, el compilador no permitirá cambiar<br />
el tipo de retorno de una función sobreescrita (lo permitiría si f() no fuera virtual).<br />
ésta es una restricción importante porque el compilador debe garantizar que<br />
se pueda llamar de forma "polimórfica" a la función a través de la clase base, y si la<br />
clase base está esperando que f() devuelva un int, <strong>en</strong>tonces la versión de f() de la<br />
clase derivada debe mant<strong>en</strong>er ese compromiso o si no algo fallará.<br />
La regla que se <strong>en</strong>seño <strong>en</strong> el capítulo 14 todavía funciona: si se sobreescribe una<br />
de las funciones miembro sobrecargadas de la clase base, las otras versiones sobrecargadas<br />
estarán ocultas <strong>en</strong> la clase derivada. En el main() el código de Derived4<br />
muestra lo que ocurre incluso si la nueva versión de f() no está actualm<strong>en</strong>te sobreescribi<strong>en</strong>do<br />
una función virtual exist<strong>en</strong>te de la interfaz - ambas versiones de f() <strong>en</strong><br />
la clase base estan ocultas por f(int). Sin embargo, si se hace un upcast de d4 a B-<br />
ase, <strong>en</strong>tonces únicam<strong>en</strong>te las versiones de la clase base estarán disponibles (porque<br />
es el compromiso de la clase base) y la versión de la clase derivada no está disponible<br />
(debido a que no está especificada <strong>en</strong> la clase base).<br />
15.9.1. Tipo de retorno variante<br />
La clase Derived3 de arriba vi<strong>en</strong>e a sugerir que no se puede modificar el tipo<br />
de retorno de una función virtual cuando es sobreescrita. En g<strong>en</strong>eral es verdad, pero<br />
hay un caso especial <strong>en</strong> el que se puede modificar ligeram<strong>en</strong>te el tipo de retorno. Si<br />
se está devolvi<strong>en</strong>do un puntero o una refer<strong>en</strong>cia a una clase base, <strong>en</strong>tonces la versión<br />
sobreescrita de la función puede devolver un puntero o una refer<strong>en</strong>cia a una clase<br />
derivada. Por ejemplo:<br />
//: C15:VariantReturn.cpp<br />
// Returning a pointer or refer<strong>en</strong>ce to a derived<br />
// type during ovverriding<br />
#include <br />
#include <br />
using namespace std;<br />
class PetFood {<br />
public:<br />
virtual string foodType() const = 0;<br />
};<br />
458<br />
✐<br />
✐<br />
✐<br />
✐