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 446 — #484<br />

✐<br />

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

de una sola vez con la s<strong>en</strong>t<strong>en</strong>cia:<br />

call word ptr [bx+4]<br />

Finalm<strong>en</strong>te, se retrocede el puntero de la pila para limpiar los argum<strong>en</strong>tos que se<br />

pusieron antes de la llamada. En código <strong>en</strong>samblador de C y de <strong>C++</strong> se ve a m<strong>en</strong>udo<br />

la instrucción para limpiar la lista de argum<strong>en</strong>tos pero puede variar dep<strong>en</strong>di<strong>en</strong>do<br />

del procesador o de la implem<strong>en</strong>tación del compilador.<br />

15.5.4. Instalar el vpointer<br />

Debido a que el VPTR determina el comportami<strong>en</strong>to virtual de las funciones <strong>en</strong><br />

un objeto, es crítico que el VPTR siempre esté apuntando a la VTABLE apropiada.<br />

No t<strong>en</strong>dría s<strong>en</strong>tido hacer una llamada a una función virtual antes de que esté inicializado<br />

apropiadam<strong>en</strong>te a su correspondi<strong>en</strong>te VTABLE. Por supuesto, el lugar donde<br />

se puede garantizar esta inicialización es <strong>en</strong> el constructor, pero ninguno de los ejemplos<br />

Instrum<strong>en</strong>t ti<strong>en</strong>e constructor.<br />

Aquí es donde la creación del constructor por defecto es es<strong>en</strong>cial. En los ejemplos<br />

Instrum<strong>en</strong>t, el compilador crea un constructor por defecto que no hace nada más<br />

que inicializar el VPTR. Este constructor es, obviam<strong>en</strong>te, llamado autormáticam<strong>en</strong>te<br />

por todos los objetos Instrum<strong>en</strong>t antes de que se pueda hacer nada con ellos, lo<br />

que asegura el bu<strong>en</strong> comportami<strong>en</strong>to con las llamadas a funciones virtuales.<br />

Las implicaciones de la inicialización automática del VPTR d<strong>en</strong>tro de un constructor<br />

se discute <strong>en</strong> un sección posterior.<br />

15.5.5. Los objetos son difer<strong>en</strong>tes<br />

Es importante darse cu<strong>en</strong>ta de que el upcasting sólo maneja direcciones. Si el<br />

compilador ti<strong>en</strong>e un objeto, sabe su tipo concreto y además (<strong>en</strong> <strong>C++</strong>) no se usará<br />

la ligadura dinámica para ninguna de las llamadas a funciones - o como mínimo el<br />

compilador no necesitará usar la ligadura dinámica. Por cuestiones de efici<strong>en</strong>cia, la<br />

mayoría de los compiladores usarán la ligadura estática cuando est<strong>en</strong> haci<strong>en</strong>do una<br />

llamada a una función virtual de un objeto porque sab<strong>en</strong> su tipo concreto. Aquí hay<br />

un ejemplo:<br />

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

// Early binding & virtual functions<br />

#include <br />

#include <br />

using namespace std;<br />

class Pet {<br />

public:<br />

virtual string speak() const { return ""; }<br />

};<br />

class Dog : public Pet {<br />

public:<br />

string speak() const { return "Bark!"; }<br />

};<br />

int main() {<br />

446<br />

✐<br />

✐<br />

✐<br />

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

Saved successfully!

Ooh no, something went wrong!