RTTI (运行时类型识别 ) :允许"用指向基类的指针或引用来操纵对象" 的程序能够获取到," 这些指
针或引用所指对象" 的实际派生类型。
在C++中为了支持 RTTI 提供了两个操作符:
重点:
在所有情况下, typeid 都忽略顶层的 cv 限定符 !!!!!。
1.typeid() 指出指针或引用指向对象的实际派生类型。
class Object
{
int val;
public:
Object(int x=0) :val(x){}
~Object() {}
virtual void fun(){}
};
int main()
{
Object* op = nullptr;
Object obja;
cout << typeid(op).name() << endl; //class Object *
cout << typeid(obja).name() << endl;//Object
cout << typeid(*op).name() << endl;//error //op没有指向到派生类对象
return 0;
}
cout<
派生类对象,编译报错。
我们把fun()函数的virtual 关键字去掉看看会发生什么:
class Object
{
void fun(){}
};
int main()
{
Object* op = nullptr;
Object obja;
cout << typeid(*op).name() << endl;//ok //class object
return 0;
}

为什么去掉了virtual关键字打印的是object类型?
我们猜测,去掉了关键字的typeid()是在编译时类型识别,而不是在运行时。
2.忽略CV限定符
当typeid()识别指针和引用时,const 不忽略,可以显示出来;当typeid()指向对象时,将忽略CV限定符(不显示)。
class Object
{
public:
Object(int x=0) :val(x)
{}
~Object() {}
virtual void fun(){}
};
class Base :public Object
{
public:
virtual void fun() {}
};
int main()
{
const Base base1;
const Object* ip = nullptr;
const Object* op = &base1;
Object obja;
cout << typeid(*op).name() << endl; //class
cout << typeid(obja).name() << endl;
cout << typeid(ip).name() << endl;
return 0;
}

一个带有函数模板的小例子:
class Object
{
int val;
public:
Object(int x=0) :val(x)
{}
~Object() {}
virtual void fun()
{
}
};
class Base :public Object
{
public:
virtual void fun() {}
};
template<class T>
void func(T& x)
{
cout << typeid(x).name();//class object
T y;
cout << typeid(y).name();
}
int main()
{
Object obja(10);
Object objb(20);
func(obja);
return 0;
}

以下程序的问题?
template<class T>
void func(T& x)
{
cout << typeid(x).name();
T y;//error const 常性类型必须要初始化
cout << typeid(y).name();
}
int main()
{
const int a = 10;
func(a);
return 0;
}

语法:dynamic_cast < typen_ame> ( expression )
说明:dynamic_cast 操作符, 它允许在运行时刻进行类型转换 ,从而使程序能够在一个类层次结构中安全地转换类型, 把基类指针转换成派生类指针,或把指向基类的左值转换成派生类的引用。
必须是公有继承,基类要有虚函数。
特点:
会出现一个什么潜在的危险?几个错误和一个正确的例子(把person*p= 那行代码指向改改再试试)

那么动态转换的原理是什么?

在这里插入代码片

都是静态转换
不用转换关键字也可以。