一、dynamic_cast<T>(exp)
用于运行时检查该转换是否类型安全
基类指针或引用向子类转换
只能操作指针或者引用 。
将基类指针向派生类指针转换,失败返回nullptr
,成功返回对象。
如果是引用,转型失败抛异常。
类中必须要有一个虚函数,应该是dynamic_cast
会用虚函数,或虚函数表。
说是用RTTI来判断。
RTTI
RTTI(Run-Time Type Information),通过运行时类型信息程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型。
二、static_cast<T>(exp)
最常用的类型转换
非指针和引用类型
int与float之间等
指针之间
可以将基类类型的指针转向派生类,而且调用派生类的函数。即使这个指针指向的是基类类型。
指针之间 的转换必须得是继承的关系。没有任何关系的指针之间不能转换
他可以将指向基类的指针转换为指向派生类的指针而且能够调用派生类的成员函数。
class A
{
public:
virtual void say();
};
class B :public A
{
public:
virtual void say();
void say1();
int i;
std::string ii;
};
int main()
{
A *a=new A;
std::cout<<"Aa "<<a<<" sizeof "<<sizeof(*a)<<std::endl;
B *b=static_cast<B*>(a);
std::cout<<"Bb "<<a<<" sizeof "<<sizeof(*b)<<std::endl;
b->say1();
b->say();
std::cout<<"b.i "<<b->i<<std::endl;
}
输出
从输出来看,指针相同,但是大小不同。可以看出应该是扩充出来的。
从执行的函数来看,如果基类有这个函数,就执行基类的。否则执行转型类的。
但是,从B的i的值可以看出,类并没有初始化。即使在默认构造函数中赋值,也不会初始化。
如果类B内,有必须要初始化的变量,比如const
之类的,编译器会报错。
不知道,为什么能这样。
同时也可以增加变量的常量性
const_cast<T>(exp)
去除变量的const
const B * const b=new B;
std::cout<<"b.i "<<b->i<<" size "<<sizeof(*b)<<std::endl;
std::cout<<"b p "<<b<<std::endl;
B *c=const_cast<B*>(b);
c->i=2;
std::cout<<"change"<<std::endl;
std::cout<<"b.i "<<b->i<<" size "<<sizeof(*b)<<std::endl;
std::cout<<"b p "<<b<<std::endl;
输出
从输出来看,确实是修改了。而且确实是在原来对象上修改的。
reinterpret_cast<t>(exp)
重新解释
int i1(0);
int i(0);
std::cout<<"int i size "<<sizeof(i)<<" piont "<<&i<<std::endl;
std::cout<<"int i1 size "<<sizeof(i)<<" piont "<<&i1<<std::endl;
double *c=reinterpret_cast<double *>(&i);
std::cout<<"double c size "<<sizeof(*c)<<" piont "<<c<<std::endl;
std::cout<<"c "<<*c<<std::endl;
输出
取后者大小的地址,对其进行重新解释。
implicit_cast<>()
这是boost库中的转型。yu