参考:C++类型转换:dynamic_cast(二)
#include<iostream>
#include<string>
#include<vector>
#include <list>
#include <map>
#include<iomanip>
#include<typeinfo>
using namespace std;
class A
{
public:
A() :_a(10) {}
virtual void func()
{
cout << "A::func()" << endl;
}
//如果设置为private后则它不会被子类B继承,所以在下面赋值兼容的时候不能使用这个成员
//private:
int _a;
};
class B :public A
{
public:
B() :_a(100), _b(88) {}
virtual void func()
{
cout << "B::func()" << endl;
}
void foo()
{
cout << "B::foo()" << endl;
}
int _a;
int _b;
};
//转换为目标指针
#if 0
/********************************************
因为C++中类型很重要,如果写成A* a = new A(); 则a是A的指针,
编译器按A的结构来认识他,不可能知道B中的东西,
如果写成A* a = new B(); 编译器按B的结构来认识它,
dynamic_cast只是确认下a指示的是不是B的结构而已
********************************************/
int main()
{
cout << "转换为目标指针" << endl;
//注意这里不能写成A* a=new A();
//A* a = new B(); //这么写也可以
B b;
A* a = &b; //赋值兼容 子类对象的地址赋值给父类指针
cout << "a->_a= " << a->_a << endl; //10
a->func(); //B::func() 由于b中virtual函数的覆写已经覆盖了虚函数表中A::func(),所以会调用B::func()
if (B* b = dynamic_cast<B*>(a))
{
cout << "change success!!!" << endl;
b->func();
//成功转换后则可以调用子类中自己特有的函数了
b->foo();
cout << "b->_a= " << b->_a << endl; //100 虽然父子类中有重名的_a,但是俩者是俩个独立的存在
cout << "b->_b= " << b->_b << endl; //88 _b为b中独有的成员
}
else
{
cout << "change fail!!!" << endl;
//转换失败则不能使用指针b,只能使用指针a的操作
a->func();
cout << "a->_a= " << a->_a << endl;
}
}
/*********************************
a->_a= 10
B::func()
change success!!!
B::func()
B::foo()
b->_a= 100
b->_b= 88
*********************************/
#endif
//转换为目标引用
#if 1
int main()
{
cout << "转换为目标引用" << endl;
A a1;
B b;
A& a=a1; //会导致转换失败,走catch逻辑
//A& a = b; //赋值兼容
cout << "a->_a= " << a._a << endl; //10
a.func(); //B::func() 由于b中virtual函数的覆写已经覆盖了虚函数表中A::func(),所以会调用B::func()
try
{
B&b = dynamic_cast<B&>(a);
//成功则使用b
cout << "change success!" << endl;
b.func();
b.foo();
cout << "b._a= " << b._a << endl; //100
cout << "b._b= " << b._b << endl; //88
}
catch (std::bad_cast)
{
//失败则处理类型转换失败的情况
cout << "change fail!" << endl;
}
}
#endif