C++ Tutorial/Pointer/dynamic cast

Материал из C\C++ эксперт
Версия от 10:30, 25 мая 2010; Admin (обсуждение | вклад) (1 версия: Импорт контента...)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Dynamic cast

#include <iostream>
 using std::cout; // this file uses std::cout
 
 class Animal
 {
 public:
     Animal():itsAge(1) { 
        cout << "Animal constructor...\n"; 
     }
     virtual ~Animal() { 
        cout << "Animal destructor...\n"; 
     }
     virtual void Speak() const { 
        cout << "Animal speak!\n"; 
     }
 protected:
     int itsAge;
 };
 
 class Cat: public Animal
 {
 public:
     Cat() { 
        cout << "Cat constructor...\n"; 
     }
     ~Cat() { 
        cout << "Cat destructor...\n"; 
     }
     void Speak()const { 
        cout << "Meow\n"; 
     }
     void Miao() const { 
        cout << "Miao\n"; 
     }
 };
 
 class Dog: public Animal
 {
 public:
     Dog() { 
        cout << "Dog Constructor...\n"; 
     }
     ~Dog() { 
        cout << "Dog destructor...\n"; 
     }
     void Speak()const { 
        cout << "Woof!\n"; 
     }
 };
 
 
 int main()
 {
     const int NumberAnimals = 3;
     Animal* animalArray[NumberAnimals];
     
     int i;
     
     animalArray[0]  = new Dog;
     animalArray[1]  = new Cat;
     animalArray[2]  = new Cat;
 
     for (i=0; i<NumberAnimals; i++)
     {
         animalArray[i]->Speak();
 
         Cat *pRealCat =  dynamic_cast<Cat *> (animalArray[i]);
 
         if (pRealCat)
             pRealCat->Miao();
         else
             cout << "not a cat!\n";
 
         delete animalArray[i];
         cout << "\n";
     }
 
     return 0;
 }
Animal constructor...
Dog Constructor...
Animal constructor...
Cat constructor...
Animal constructor...
Cat constructor...
Woof!
not a cat!
Dog destructor...
Animal destructor...
Meow
Miao
Cat destructor...
Animal destructor...
Meow
Miao
Cat destructor...
Animal destructor...

dynamic_cast: Cast from Base * to Base *

#include <iostream>
using namespace std;
class Base {
public:
  virtual void f() {
     cout << "Inside Base\n";
  }
};
class Derived : public Base {
public:
  void f() {
     cout << "Inside Derived\n";
  }
};
int main()
{
  Base *bp, b_ob;
  Derived *dp, d_ob;
  bp = dynamic_cast<Base *> (&b_ob);
  if(bp) {
    cout << "Cast from Base * to Base * OK.\n";
    bp->f();
  } else
    cout << "Error\n";
  cout << endl;
  return 0;
}
Cast from Base * to Base * OK.
Inside Base

dynamic_cast: Cast from Base * to Derived * (wrong)

#include <iostream>
using namespace std;
class Base {
public:
  virtual void f() {
     cout << "Inside Base\n";
  }
};
class Derived : public Base {
public:
  void f() {
     cout << "Inside Derived\n";
  }
};
int main()
{
  Base *bp, b_ob;
  Derived *dp, d_ob;
  dp = dynamic_cast<Derived *> (&b_ob);
  if(dp)
    cout << "Error\n";
  else
    cout << "Cast from Base * to Derived * not OK.\n";
  cout << endl;
  return 0;
}
Cast from Base * to Derived * not OK.

dynamic_cast: Cast from Derived * to Base *

#include <iostream>
using namespace std;
class Base {
public:
  virtual void f() {
     cout << "Inside Base\n";
  }
};
class Derived : public Base {
public:
  void f() {
     cout << "Inside Derived\n";
  }
};
int main()
{
  Base *bp, b_ob;
  Derived *dp, d_ob;
  bp = dynamic_cast<Base *> (&d_ob);
  if(bp) {
    cout << "Cast from Derived * to Base * OK.\n";
    bp->f();
  } else
    cout << "Error\n";

  cout << endl;
  return 0;
}
Cast from Derived * to Base * OK.
Inside Derived

dynamic_cast: Cast from Derived * to Derived *

#include <iostream>
using namespace std;
class Base {
public:
  virtual void f() {
     cout << "Inside Base\n";
  }
};
class Derived : public Base {
public:
  void f() {
     cout << "Inside Derived\n";
  }
};
int main()
{
  Base *bp, b_ob;
  Derived *dp, d_ob;
  dp = dynamic_cast<Derived *> (&d_ob);
  if(dp) {
    cout << "Cast from Derived * to Derived * OK.\n";
    dp->f();
  } else
    cout << "Error\n";
  cout << endl;
  return 0;
}
Cast from Derived * to Derived * OK.
Inside Derived

Use dynamic_cast to replace typeid

#include <iostream>
#include <typeinfo>
using namespace std;
class Base {
public:
  virtual void f() {}
};
class Derived : public Base {
public:
  void derivedOnly() {
    cout << "Is a Derived Object.\n";
  }
};
int main()
{
  Base *bp, b_ob;
  Derived *dp, d_ob;
  // use typeid
  bp = &b_ob;
  if(typeid(*bp) == typeid(Derived)) {
    dp = (Derived *) bp;
    dp->derivedOnly();
  }
  else
    cout << "Cast from Base to Derived failed.\n";
  return 0;
}
Cast from Base to Derived failed.