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

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

✐<br />

✐<br />

✐<br />

“Volum<strong>en</strong>1” — 2012/1/12 — 13:52 — page 464 — #502<br />

✐<br />

Capítulo 15. Polimorfismo y Funciones virtuales<br />

son llamados siempre. Si se quita la definición de un destructor virtual puro, ¿a qué<br />

cuerpo de función se llamará durante la destrucción Por esto, es absolutam<strong>en</strong>te<br />

necesario que el compilador y el <strong>en</strong>lazador requieran la exist<strong>en</strong>cia del cuerpo de una<br />

función para un destructor virtual puro.<br />

Si es puro, pero la función ti<strong>en</strong>e cuerpo ¿cuál es su valor La única difer<strong>en</strong>cia que<br />

se verá <strong>en</strong>tre el destructor virtual puro y el no-puro es que el destructor virtual puro<br />

convierte a la clase base <strong>en</strong> abstracta, por lo que no se puede crear un objeto de la<br />

clase base (aunque esto también sería verdad si cualquier otra función miembro de<br />

esa clase base fuera virtual pura).<br />

Sin embargo, las cosas son un poco confusas cuando se hereda una clase de otra<br />

que cont<strong>en</strong>ga un destructor puro virtual. Al contrario que <strong>en</strong> el resto de las funciones<br />

virtuales puras, no es necesario dar una definición de un destructor virtual puro <strong>en</strong><br />

la clase derivada. El hecho de que el sigui<strong>en</strong>te código compile es la prueba:<br />

//: C15:UnAbstract.cpp<br />

// Pure virtual destructors<br />

// seem to behave strangely<br />

class AbstractBase {<br />

public:<br />

virtual ~AbstractBase() = 0;<br />

};<br />

AbstractBase::~AbstractBase() {}<br />

class Derived : public AbstractBase {};<br />

// No overriding of destructor necessary<br />

int main() { Derived d; } ///:~<br />

Normalm<strong>en</strong>te, una función virtual pura <strong>en</strong> una clase base causará que la clase derivada<br />

sea abstracta a m<strong>en</strong>os que esa (y todas las demás funciones virtuales puras)<br />

t<strong>en</strong>gan una definición. Pero aquí, no parece ser el caso. Sin embargo, hay que recordar<br />

que el compilador crea automáticam<strong>en</strong>te una definición del destructor <strong>en</strong> todas las<br />

clases si no se crea una de forma explícita. Esto es lo que sucede aquí - el destructor<br />

de la clase base es sobreescrito de forma oculta, y una definición es puesta por el<br />

compilador por lo que Derived no es abstracta.<br />

Esto nos brinda una cuestión interesante: ¿Cuál es el s<strong>en</strong>tido de un destructor<br />

virtual puro Al contrario que con las funciones virtuales puras ordinarias <strong>en</strong> las<br />

que hay que dar el cuerpo de una función, <strong>en</strong> una clase derivada de otra con un<br />

destructor virtual puro, no se está obligado a implem<strong>en</strong>tar el cuerpo de la función<br />

porque el compilador g<strong>en</strong>era automáticam<strong>en</strong>te el destructor. Entonces ¿Cuál es la<br />

difer<strong>en</strong>cia <strong>en</strong>tre un destructor virtual normal y un destructor virtual puro<br />

La única difer<strong>en</strong>cia ocurre cuando se ti<strong>en</strong>e una clase que sólo ti<strong>en</strong>e una función<br />

virtual pura: el destructor. En este caso, el único efecto de la pureza del destructor<br />

es prev<strong>en</strong>ir la instanciación de la clase base, pero si no exist<strong>en</strong> otros destructores<br />

<strong>en</strong> las clase heredadas, el destructor virtual se ejecutará. Por esto, mi<strong>en</strong>tras que el<br />

añadir un destructor virtual es es<strong>en</strong>cial, el hecho de que sea puro o no lo sea no es<br />

tan importante.<br />

Cuando se ejecuta el sigui<strong>en</strong>te ejemplo, se puede ver que se llama al cuerpo de la<br />

función virtual pura después de la versión que está <strong>en</strong> la clase derivada, igual que<br />

464<br />

✐<br />

✐<br />

✐<br />

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

Saved successfully!

Ooh no, something went wrong!