(9个答案)
七年前关闭的
我已经写了C和C++代码将近二十年了,但是这些语言的一个方面我从来没有真正理解。我显然用过常规的石膏,比如
MyClass*m=(MyClass*)ptr;
到处都是,但似乎还有另外两种类型的演员,我不知道有什么区别。以下代码行之间有什么区别
MyClass*m=(MyClass*)ptr;
MyClass*m=静态投影<;MyClass*>;(ptr);
MyClass*m=动态投影<;MyClass*>;(ptr);
静态浇铸
`static_cast`用于基本上想要反转隐式转换的情况,但有一些限制和添加`static_cast`不执行运行时检查。如果您知道您引用的是特定类型的对象,那么应该使用此选项,因此不需要进行检查。例子:
void func(void*数据){
//MyClass*->;void*的转换是隐式的
MyClass*c=静态转换<;MyClass*>;(数据);
...
}
int main(){
MyClass c;
start_线程(&;func,&;c)//将调用func(&;c)
.join();
}
在本例中,您知道您传递了一个MyClass对象,因此不需要运行时检查来确保这一点
动态浇铸
`当您不知道对象的动态类型时,dynamic_cast`非常有用。如果引用的对象不包含作为基类强制转换到的类型,则返回空指针(当您强制转换到引用时,在这种情况下会引发“bad_cast”异常)。
if(JumpStm*j=dynamic_cast<;JumpStm*>;(&;stm)){
...
}else if(ExprStm*e=dynamic_cast<;ExprStm*>;(&;stm)){
...
}
如果向下转换(转换到派生类)并且参数类型不是多态的,则不能使用dynamic\u cast。例如,以下代码无效,因为Base不包含任何虚拟函数:
结构基{};
派生结构:基{};
int main(){
派生d;基*b=&;d;
动态_cast<;派生*>;(b);//无效
}
“;“向上投射”;(强制转换到基类)始终与静态强制转换和动态强制转换一起有效,也不与任何强制转换一起有效,例如;“向上投射”;是一个隐式转换(假设基类是可访问的,即它是public继承)
普通演员
这些类型转换也称为C样式转换。C样式的CAST基本上与尝试一系列C++的Casts相一致,并且采用第一个C++的Cask,而不考虑 DyrimCysCAP。不用说,它结合了所有的const\u cast、static\u cast和reinterpret\u cast,因此功能更强大,但它也不安全,因为它不使用dynamic\u cast
此外,C风格的强制转换不仅允许您这样做,还允许您安全地强制转换到私有基类,而;等价物static\u castsequence会给您一个编译时错误
有些人喜欢C风格的演员,因为他们的简短。我只使用它们进行数值转换,当涉及到用户定义的类型时,使用适当的C++转换,因为它们提供了更严格的检查。