VPTR en c++

mdx4

Bovino maduro
#1
Hola a todos, espero puedan ayudarme o darme una pista para resolver mi tarea.
Estoy viendo métodos virtuales en C++ y el profe nos dió el siguiente código:
Código:
#include <iostream>
using namespace std;
enum Nota {DO, RE, MI, FA, SOL};
class Instrumento{
public:
  virtual void tocar(Nota)const {
    cout << "Instrumento::void tocar" << endl;
  }
  virtual char* queClase() const{
    return "Instrumento";
  }
  virtual void escuchar(int) {cout<<"Escuchando\n";}
};
class Viento: public Instrumento{
public:
  virtual void tocar(Nota)const {
    cout << "Viento::void tocar" << endl;
  }
  virtual char* queClase() const{
    return "Viento";
  }
  virtual void escuchar(int) {}
};
class VientoMadera: public Viento{
public:
  void tocar(Nota)const {
    cout << "VientoMadera::void tocar" << endl;
  }
  virtual char* queClase() const{
    cout<<"queclase\n";
    return "VientoMadera";
  }
};
void afinar(Instrumento& i){
  i.tocar(DO);
}
void f(Instrumento& i){
  i.escuchar(123);
}
int main(){
  VientoMadera vm;
  afinar(vm) ;
[COLOR=Red]  // tu código que modifica la VPTR de vm[/COLOR]
  afinar(vm) ;
  return 0;
}
A grandes rasgos, se tiene una clase Instrumento con varios métodos virtuales, uno de ellos es tocar, luego una clase Viento que hereda de Instrumento y redefine el método tocar, y finalmente, una clase VientoMadera, que hereda de Viento y que vuelve a redefinir el método tocar. También se tiene la función afinar que recibe un objeto tipo Instrumento y llama a su método tocar.

Lo que tengo que hacer es modificar la tabla de apuntadores virtuales (VPTR) del objeto vm(de la clase VientoMadera), de tal manera que la segunda vez que se llama a la función afinar , utilice el método de la clase principal (clase Instrumento) en lugar del método del objeto vm.

Hasta ahora lo más que he podido hacer es crear apuntadores a las funciones tocar del objeto vm y de un objeto de la clase Instrumento:
(Me tomé la libertad de cambiar un poco el código del profe)

Código:
typedef void(*fun)(Nota);
int main(){
  VientoMadera vm;
  Instrumento ins;
  fun pv,pi;
  pv=(fun)*((int*)*(int*)(&vm+0)+0); //función tocar de vm
  pi=(fun)*((int*)*(int*)(&ins+0)+0); //función tocar de ins
  pi(DO); //llama a la función tocar de ins 
  pv(DO); //llama a la función tocar de pv 
  pv=pi; //cambia el apuntador de pv para que sea igual a pi
  pi(DO); //llama a la función tocar de ins 
  pv(DO); //llama a la función tocar de ins 
  return 0;
}
Se supone que en pi y en pv tengo ya las direcciones de las funciones tocar de Instrumento y de VientoMadera, ahora mi problema es cómo poner esas direcciones en la tabla vptr.

Alguién tiene una idea?

De antemano, les doy las gracias :)

Edit:
Ya lo resolvi, la solucion está en estas cuantas lineas de codigo:

Código:
int main(){ 
  VientoMadera vm; 
  Instrumento ins; 
  int*x; 
  int*y; 
  afinar(vm); 
  x=(int*)((int*)(&vm+0)+0); //Dirección del VPTR de vm 
  y=(int*)((int*)*(int*)(&ins+0)+0); //Dirección de la función tocar(Nota) de ins 
  *x=(int)y; //Se cambia el apuntador de vm para que apunte a la función de ins 
  afinar(vm); 
  return 0; 
}
Espero que algún día le pueda servir a alguien
 
Arriba