13.01.2015 Views

Pensar en C++ (Volumen 1) - Grupo ARCO

Pensar en C++ (Volumen 1) - Grupo ARCO

Pensar en C++ (Volumen 1) - Grupo ARCO

SHOW MORE
SHOW LESS

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 />

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!