//Emplyee.h class Employee { public: virtual int salary(); }; class Manager : public Employee { public: int salary(); }; class Programmer : public Employee { public: int salary(); };
class MyCompany { public: void payroll(Employee *pe); // }; void MyCompany::payroll(Employee *pe) { //do something }
//Emplyee.h class Employee { public: virtual int salary(); virtual int bonus(); }; class Manager : public Employee { public: int salary(); }; class Programmer : public Employee { public: int salary(); int bonus(); }; //Emplyee.cpp int Programmer::bonus() { // }
payroll()通过多态来调用bonus():
class MyCompany { public: void payroll(Employee *pe); // }; void MyCompany::payroll(Employee *pe) { //do something //pe->bonus(); }
//Emplyee.h class Employee { public: virtual int salary(); }; class Manager : public Employee { public: int salary(); }; class Programmer : public Employee { public: int salary(); int bonus();//直接在这里扩展 }; //somewhere.cpp int Programmer::bonus() { //define }
class MyCompany { public: void payroll(Employee *pe); // }; void MyCompany::payroll(Employee *pe) { Programmer *pm = dynamic_cast<Programmer *>(pe); //如果pe实际指向一个Programmer对象,dynamic_cast成功,并且开始指向Programmer对象起始处 if(pm) { //call Programmer::bonus() } //如果pe不是实际指向Programmer对象,dynamic_cast失败,并且pm = 0 else { //use Employee member functions } }
dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。
在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
class Base { public: int m_iNum; virtual void foo(); }; class Derived:public Base { public: char *m_szName[100]; }; void func(Base *pb) { Derived *pd1 = static_cast<Derived *>(pb); Derived *pd2 = dynamic_cast<Derived *>(pb); }
class Base { public: int m_iNum; virtual void f(){} }; class Derived1 : public Base { }; class Derived2 : public Base { }; void foo() { derived1 *pd1 = new Drived1; pd1->m_iNum = 100; Derived2 *pd2 = static_cast<Derived2 *>(pd1); //compile error Derived2 *pd2 = dynamic_cast<Derived2 *>(pd1); //pd2 is NULL delete pd1; }在函数foo中,使用static_cast进行转换是不被允许的,将在编译时出错;而使用 dynamic_cast的转换则是允许的,结果是空指针。
“…cannot convert from 'const class C *' to 'class C *'”。
常量指针被转化成非常量指针,并且仍然指向原来的对象;常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。
//Voiatile和const类试。举如下一例: class B{ public: int m_iNum; } void foo(){ const B b1; b1.m_iNum = 100; //comile error B b2 = const_cast<B>(b1); b2. m_iNum = 200; //fine }上面的代码编译时会报错,因为b1是一个常量对象,不能对它进行改变;使用const_cast把它转换成一个常量对象,就可以对它的数据成员任意改变。注意:b1和b2是两个不同的对象。
四种cast方法的典型用法示例:
#include <iostream> using namespace std; class Base { public: int _base; virtual void printinfo() { cout << _base << endl; } }; class Derived : public Base { public: int _derived; virtual void printinfo() { cout << _derived << endl; } }; int main(void) { Base b1; Derived d1; int aInt = 10; long aLong = 11; float aFloat = 11.11f; double aDouble = 12.12; Derived* pd = static_cast<Derived*>(&b1); // down-casting 不安全 Base* pb = static_cast<Base*>(&d1); // up-casting 安全 Derived& d = static_cast<Derived&>(b1); // down-casting 不安全 Base& b = static_cast<Base&>(d1); // up-casting 安全 aInt = static_cast<int>(aFloat); // 基本数据类型转换 void* sth = static_cast<void*>(&aDouble); // 将double指针类型转换成void指针类型 double* bDouble = static_cast<double*>(sth); // 将void指针类型转换成double指针类型 cout << *bDouble << endl; Base* pb1 = dynamic_cast<Base*>(&d1); //Derived* pd1 = dynamic_cast<Derived*>(&b1); // 编译时有warning,运行时出错 int bInt = reinterpret_cast<int>(pb1); // 将地址或指针转换成整数 cout << bInt << endl; pb1 = reinterpret_cast<Base*>(bInt); // 将整数转换成地址或指针 int* cInt = reinterpret_cast<int*>(&aFloat); // 这个转换的结果会出乎意料 cout << (int)*cInt << endl; const Base* bBase = new Base(); Base* cBase = const_cast<Base*>(bBase); //Base* dBase = dynamic_cast<Base*>(bBase); // 不能通过编译 //Base* eBase = static_cast<Base*>(bBase); // 不能通过编译 //Base* fBase = reinterpret_cast<Base*>(bBase); // 不能通过编译 return 0; }