static_cast 、const_cast、dynamic_cast、reinterpret_cast 关键字简单解释

时间:2022-12-05 04:23:59

static_cast const_cast、dynamic_castreinterpret_cast 关键字简单解释:

Static_cast 静态类型转换

①用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。

进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;

进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。

②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。

③把空指针转换成目标类型的空指针。

④把任何类型的表达式转换成void类型。

const_cast 常量类型转换

一、常量指针被转化成非常量的指针,并且仍然指向原来的对象;

二、常量引用被转换成非常量的引用,并且仍然指向原来的对象;

dynamic_cast动态类型转换

dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。

在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;

在进行下行转换时,dynamic_cast具有类型检查的功能,downcast不成功返回null,比static_cast更安全,static_cast的问题只有在运行时才能体现出来(错误解释)。对于dynamic_cast下行转换基类要有虚函数,因为运行时信息保存在虚表中,如果没有会编译错误;

reinterpret_cast 重新解释类型转换

reinterpret_cast运算符是用来处理无关类型之间的转换;它会产生一个新的值,这个值会有与原始参数(expressoin)有完全相同的比特位;reinterpret_cast用在任意指针(或引用)类型之间的转换;以及指针与足够大的整数类型之间的转换;从整数类型(包括枚举类型)到指针类型,无视大小. (所谓"足够大的整数类型",取决于操作系统的参数,如果是32位的操作系统,就需要整形(int)以上的;如果是64位的操作系统,则至少需要长整形(long)。具体大小可以通过sizeof运算符来查看)

请看下面的代码:

class A{
private :
int x;
public:
A():x(1){
cout << "A"<<endl;
}
void print(){
cout <<"print A "<<x<<endl;
}
~A(){
cout << "~A"<<endl;
}
}; class B{
private:
int x;
public: B():x(2){
cout << "B"<<endl;
}
void print(){
cout <<"print B "<<x<<endl;
}
~B(){
cout << "~B"<<endl;
}
}; int main()
{
A *pa=new A();
B * pb =(B*)pa; // static_cast<B*>(pa) 非法; reinterpret_cast<B*>(pa) ,合法
pb->print(); //print B 1
delete pa;
return 0;
}

main函数中之所以会print B 1是因为, pb->print(), 调用的是B::print(), 然而在在访问数据成员x时,传入的this指针是pa的值,由于两个类的内存布局完全一样,所以this->x就是A::x 而不是B::x。

强调: C中类型转换是不安全的,因为他不进行类型检查。所以才会出现这个问题,如果用C++中的上述几个关键字则不会出现该问题