分别是
static_cast、const_cast、reinterpret_cast、dynamic_cast
static_cast
任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast。在编译期间处理,但是没有运行时类型的检测来保证转换的安全性。在C++中,某些类型之间存在相关的依赖关系。若两种类型相关,则可在需要某种类型的操作数位置上,使用该类型的相关类型对象或值。如果两个类型之间可以相互转换,则称这两个类型相关。static_cast就是处理这种类型相关的转换。
reinterpret_cast
与之相反,类型不相关之间的类型转换就用reinterpret_cast,reinterpret_cast通常为运算对象的位模式提供较底层次上的重新解释。比如int和char之间的转换。
const_cast
使用const_cast会消除被转换类型的const特性,而且只有const类型的变量才能使用。那么,什么情况下需要消除一个const变量的const特性呢?比如,有时候有的函数的形参类型为非const类型,那么如果你要将一个const类型的参数传入就会报错。所以在这种情况下需要先使用const_cast转化一下。“去掉const性质”只用于改变常量属性。
dynamic_cast
它是一种作运行时(run-time)检测的类型转换。它可以将基类类型的指针或引用安全地转换为派生类型的指针或引用。当具有基类的引用或指针,但需要执行不是基类组成部分的派生类操作的时候,需要动态的强制类型转换。通常,从基类指针获得派生类行为最好的方法是通过虚函数。当使用虚函数的时候,编译器自动根据对象的实际类型选择正确的函数。但是,在某些情况下,不可能使用虚函数。这时候就需要使用dynamic_cast关键字了。但是,能用虚函数还是用虚函数最好。与其他强制类型转换不同,dynamic_cast涉及运行时类型检查。如果绑定到引用或指针的对象不是目标类型的对象,则dynamic_cast失败。dynamic_cast 失败的时候,如果要转的是指针,返回空指针;如果是引用,抛 std::bad_cast
dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
classB
{
public:
int m_iNum;
virtual void foo();
};
classD:publicB
{
public:
char* m_szName[100];
};
void func(B* pb)
{
D* pd1=static_cast<D*>(pb);
D* pd2=dynamic_cast<D*>(pb);
}
在上面的代码段中,如果 pb 指向一个 D 类型的对象,pd1 和 pd2 是一样的,并且对这两个指针执行 D 类型的任何操作都是安全的;但是,如果 pb 指向的是一个 B 类型的对象,那么 pd1 将是一个指向该对象的指针,对它进行 D 类型的操作将是不安全的(如访问 m_szName),而 pd2 将是一个空指针。
另外要注意:B 要有虚函数,否则会编译出错;static_cast则没有这个限制。
这是由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表(关于虚函数表的概念,详细可见