C++转型对比
Opened this issue · 0 comments
guodongxiaren commented
从C时代开始。转型主要分为两种:
- 显式类型转换
- 隐式类型转换
显示类型转换
显式类型转换C
极度不安全。对于不相关类型(非继承)的指针也可以转换……(其实反过来也可以利用)
static_cast<>c++
比C风格转型,安全性上高一些。可以识别出不相关类型指针的转换。在编译期间报错。
比如(clang):
error: static_cast from 'A *' to 'B *', which are not related by inheritance, is not allowed
dynamic_cast<>c++
要点:
- 原类型含有虚函数
- 模板类型要是指针或者引用
错误1:转换成非指针/引用类型
B b = dynamic_cast<B>(a);
error: 'B' is not a reference or pointer
错误2:给不带虚函数的类型指针转换
用dynamic_cast给不带虚函数的类型指针转换。报错:
A *pa = new A;
A a;
B* pb = dynamic_cast<B*>(pa);
B b = dynamic_cast<B&>(a);
上面两次转换都报错:
error: 'A' is not polymorphic
给类A加上一个virtual的函数。再抓成不相关的类型B。
不报错。
正确用法
class A {
public:
virtual void echo() {
cout<<"A"<<endl;
}
};
class B {
public:
void echo() {
cout<<"B"<<endl;
}
};
int main() {
A *a = new A;
B* b = dynamic_cast<B*>(a);
b->echo(); // 输出 B
return 0;
}
指针下行转换(能编译通过)
父类指针转换为子类指针,编译不失败。两种情况:
- 父类指针指向的实际是子类对象。成功转型。
- 父类指针指向的就是父类对象。编译无异常,只是返回值是NULL。
dynamic_cast无二义性。不会一个编译通过,一个不通过。而实际转型成功与否交给实际情况去判断。这个其实就是RTTI!
reinterpret_cast <>c++
最不安全的类型转换。像C转换一样,两个指针可以毫不相干。
另外它也要求转换目标类型为指针或者引用。
const_cast<>c++
消除const属性!一般工作中被禁止使用。
总结
上行转换,通常安全。下行转换很可能不安全。
static_cast效率比dynamic_cast高。因为RTTI效率更低。
但static_cast可能不够安全!
个人总结,只有父类有虚函数,就用dynamic_cast。没有就用static_cast。