1.概念差异
static_cast:在编译时进行静态类型转换,不进行运行时检查,适用于非多态类型转换有效。 dynamic_cast:运行时通过RTTI(运行时类型信息),验证对象实际类型,确保转换的合法性,主要确保 多态类型的安全机制。
2.安全机制方面
对于常见的向上类型转换(本身安全,例如:父类指针指向子类对象),但是对于向下转型, static_cast 不安全,需要手动进行验证,但是对于dynamic_cast就是安全且自动检查的, 可以判断出,转换是否有效。
3.作用范围方面
static_cast,支持基本的类型转换,类继承层次的上行转换,但是无法处理多态类型的交叉转换。(零运行开销,仅调整 编译器类型解释方式) dynamic_cast,仅适合含有虚函数的类(多态环境),支持向下转型和交叉转换。(运行时通过虚表查询RTTI,存在性能损耗)
4.实例理解
4.1 static_cast
继续要知晓的概念: 指针和引用的向上、向下转换 向上转换(子类--> 父类),安全,子类包含有父类的所有成员 向下转换(父类--> 子类),需要程序员确认装换的安全性,否则可能导致未定义行为 有无符号数操作
unsigned int number5 = 5;
int number6 = -1;
if(number5 > number6) //出现了一个无符号,统一按照无符号进行比较的
{
cout<<"---unsigned int > number6 is normal "<<endl;
}
if(static_cast<int>(number5) > number6) //强制转换成有符号,再进行比较
{
cout<<"--force to int ,than number5 is large"<<endl;//强制变成int,进行比较,就是正常程序员理解的行为。
}
显式进行转换(用户要自己负责进行检查!!)
class base{
public:
int age;
public:
base(int _age):age(_age){}
base(){}
};
class derived : public base{
public:
int age;
public:
derived(int _age):age(_age){}
};
//向上--本身安全
base *_base_obj_ptr = nullptr;
derived _derived_obj(23);
_base_obj_ptr = static_cast<base *>(&_derived_obj); // 显式进行转换,隐式转换也可以
// cout<<"---the derived obj member age: "<<_base_obj_ptr->derived::age <<endl; //这个是不可以访问的,因为derived::age 不是 base成员
//向下,---不安全!!!, 需要注意类型,以下例子虽然可以编译通过,但是运行可能异常,因为父类
实际指向就是子类对象,隐式不允许转换,显式转换,用户自己保证!!
base *_base_obj_ptr2 = new base(44);
derived *_derived_ptr2 = static_cast<derived *>(_base_obj_ptr2);
cout<<"-the dervied member, invalid: "<<_derived_ptr2->age<<endl;//这个编译通过,运行不符合预期!!
您还没有登录,请您登录后发表评论。