// conversiones.cpp
#include <iostream>
using namespace std;

class CB
{
    int b;
  public:
    CB(int x = 10) { b = x; }
    virtual void f(){ cout << "CB\n"; }
    int obtener() { cout << "CB: "; return b; }
};

class CD : public CB
{
    int d;
  public:
    CD(int x = 20) { d = x; }
    void f(){ cout << "CD\n"; }
    int obtener() { cout << "CD: "; return d; }
};

void fx(CB& r);

int main()
{
  CB* pb1 = new CB;
  CB* pb2 = new CD;

  CD* pd1 = dynamic_cast<CD*>(pb1); // pd1 = 0 (no conversión)
  if (pd1)
  {
    pd1->f();
    cout << pd1->obtener() << endl;
  }
  
  CD* pd2 = dynamic_cast<CD*>(pb2); // correcto
  if (pd2)
  {
    pd2->f();                        // escribe CD
    cout << pd2->obtener() << endl;  // escribe 20
  }
  
  try
  {
    fx(*pb1);
  }
  catch(bad_cast)
  {
    cout << "conversión entre referencias no permitida\n";
  }
  
  const type_info& info1 = typeid(pb1);
  cout << info1.name() << endl;
  cout << typeid(pd2).name() << endl;  
  if (info1 != typeid(pd2)) cout << info1.before(typeid(pd2)) << endl;
  
  delete pb1;
  delete pb2;
}

void fx(CB& r)
{
  CD& r1 = dynamic_cast<CD&>(r);
  // ...
}

