Pensar en C++ (Volumen 1) - Grupo ARCO
Pensar en C++ (Volumen 1) - Grupo ARCO
Pensar en C++ (Volumen 1) - Grupo ARCO
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 />
✐