简单围绕几种转换机制说一下。
参考如下链接:[static_cast、dynamic_cast、const_cast和reinterpret_cast总结]
static_cast
- static_cast的转换格式:static_cast (expression).
- 将expression转换为type-id类型,主要用于非多态类型之间的转换,不提供运行时的检查来确保转换的安全性。
其实从上面说的我们已经看出来了,既然不提供运行时检查来确保转换的安全性,那么就说明了,多态肯定是不支持的,因为多台就是在运行时才能确定类型。
static_cast我自己理解它的功能主要是兼容c中的强制转换。
#include <iostream>
class A {
public:
virtual void print(){ std::cout << "class A." << std::endl; };
};
class B : public A {
public:
virtual void print(){ std::cout << "class B" << std::endl; }
};
int main(){
A* pa = new A();
A* pb = new B();
B* pp = static_cast<B*>(pa);
pp->print(); // 输出class A.
return 0;
}
dynamic_cast
将一个基类对象指针(或引用)cast到继承类指针,dynamic_cast会根据基类指针是否真正指向继承类指针来做相应处理。
从上面的分析可知,下行转换没什么好说的。但是上行转换的时候,如果基类的指针指向派生类的对象,那么你将这个指针转换为派生类的指针没有什么问题。但是,如果基类的指针指向的是基类的对象,此时是不能转化为派生类对象的,因为解引用之后类型不兼容。
- 注意:
派生类需要有虚函数。否则没有vtable,怎么存rtti信息。
#include <iostream>
class A {
public:
virtual void print(){ std::cout << "class A." << std::endl; };
};
class B : public A {
public:
virtual void print(){ std::cout << "class B" << std::endl; }
};
int main(){
A* pa = new A(); // 指向基类
B* pb1 = static_cast<B*>(pa); // 这个操作应该是非法的,但是却可以完成转换,虽然是错的。
if( pb1 ) std::cout << "OK" << std::endl;
else std::cout << "No" << std::endl;
pb1 = dynamic_cast<B*>(pa); // 动态转换的时候会检查类型信息,如果不兼容,则会置NULL.
if( pb1 ) std::cout << "OK" << std::endl;
else std::cout << "No" << std::endl;
delete pa;
return 0;
}
const_cast
const_cast用来将类型的const、volatile和__unaligned属性移除。常量指针被转换成非常量指针,并且仍然指向原来的对象;常量引用被转换成非常量引用,并且仍然引用原来的对象。
reinterpret_cast
reinterpret_cast是为了映射到一个完全不同类型的意思,这个关键词在我们需要把类型映射回原有类型时用到它。我们映射到的类型仅仅是为了故弄玄虚和其他目的,这是所有映射中最危险的。(这句话是C++编程思想中的原话)。
我的理解,比如都是指针类型,那么都是32byte,此时转化成不同的类型,给予编译器不同的理解视角即可。