dynamic_cast 转换示例
/* 带虚函数与不带虚函数转换的区别 dynamic_cast:必须要有虚函数才可以转换 dynamic_cast:只能处理转换指针或引用,不能转换对象 dynamic_case 只能识别多态数据类型,转换失败就是null 多态,父类指针可以根据多态转化为子类指针 子类指针存储一个父类指针,转换失败。指针为 00000 子类指针转换成父类,自动转换 typeid:自动识别类型,依赖于虚函数 //虚函数重载和返回值无关 和参数的类型 个数 顺序有关 //虚函数被继承下来了还是虚函数 //如果要使用被继承的虚函数 不允许出现虚函数重载和覆盖 //多态可以跨类 爷爷辈的指针 可以存储孙子辈的地址 父辈拔针的地址 */ #include <iostream> /* 没有虚函数的情况下,子类同名函数会覆盖父类, 父类指针存储子类地址: 1、有虚函数情况:调用子类方法 2、没有虚函数情况:调用父类方法 */ class base1 { public: virtual void show() { std::cout << "base1->show()" << std::endl; } }; class baseX: public base1 { public: void show() { std::cout << "baseX->show()" << std::endl; } }; class base2 { public: void show() // 注意: 不是虚函数 { std::cout << "base2->show()" << std::endl; } }; class baseY: public base2 { public: void show() { std::cout << "baseY->show()" << std::endl; } }; int main() { //多态,父类指针可以根据多态转化为子类指针 //子类指针存储一个父类指针,转换失败。指针为 0x00000000 base1 *p1 = new base1; base1 *p2 = new baseX; std::cout << "p1 addr: 0x" << p1 << " " << "p2 addr: 0x" << p2 << std::endl; p1->show(); p2->show(); //typeid:自动识别类型,依赖于虚函数 std::cout << typeid(p2).name() << std::endl; // p1的类型为父类类型指针 class base1 * std::cout << typeid(*p2).name() << std::endl; // *p1的类型为子类类型 class baseX baseX *px = dynamic_cast<baseX *>(p1); // 使用子类指针存储一个父类指针 std::cout << "px addr: 0x" << (void *)px << std::endl; // 转换失败,px的地址值为0x00000000 // px->show(); // 可以通过编译,但是运行会崩溃 base1 *pb1 = dynamic_cast<base1 *>(p2); // 使用父类指针存储一个子类指针 std::cout << "pb1 addr: 0x" << (void *)pb1 << std::endl; // 转换成功 pb1->show(); std::cout << "===========================================" << std::endl; base2 *p3 = new base2; base2 *p4 = new baseY; std::cout << "p3 addr: 0x" << p3 << " " << "p4 addr: 0x" << p4 << std::endl; p3->show(); p4->show(); //typeid:自动识别类型,依赖于虚函数 std::cout << typeid(p4).name() << std::endl; // p1的类型为父类类型指针 class base2 * std::cout << typeid(*p4).name() << std::endl; // *p1的类型为子类类型 class base2 // 注意: 这里转换失败,是因为RTTI实时类型检测到p3和py的类型是不一样的,需要进行转换 // 但是dynamic_cast转换只能识别多态数据类型,转换失败就是null // dynamic_cast:必须要有虚函数才可以转换 //baseY *py = dynamic_cast<baseY *>(p3); // 使用子类指针存储一个父类指针 //std::cout << "py addr: 0x" << (void *)py << std::endl; // 转换失败,px的地址值为0x00000000 //px->show(); // 可以通过编译,但是运行会崩溃 // 注意: 这里转换成功,是因为RTTI实时类型检测到p4和pb2的类型是一样的,无需转换,直接赋值即可 base2 *pb2 = dynamic_cast<base2 *>(p4); // 使用父类指针存储一个父类指针 std::cout << "pb2 addr: 0x" << (void *)pb2 << std::endl; // 转换成功 pb2->show(); //std::cout << "mytest" << std::endl; system("pause"); return 0; }
运行结果