guodongxiaren / Blog

【编程往事】 — 果冻虾仁 的网络博客
https://github.com/guodongxiaren/Blog/issues
42 stars 12 forks source link

C++转型对比 #34

Open guodongxiaren opened 4 years ago

guodongxiaren commented 4 years ago

从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;
}

指针下行转换(能编译通过)

父类指针转换为子类指针,编译不失败。两种情况:

dynamic_cast无二义性。不会一个编译通过,一个不通过。而实际转型成功与否交给实际情况去判断。这个其实就是RTTI

reinterpret_cast <>c++

最不安全的类型转换。像C转换一样,两个指针可以毫不相干。 另外它也要求转换目标类型为指针或者引用。

const_cast<>c++

消除const属性!一般工作中被禁止使用。

总结

上行转换,通常安全。下行转换很可能不安全。 static_cast效率比dynamic_cast高。因为RTTI效率更低。 但static_cast可能不够安全! 个人总结,只有父类有虚函数,就用dynamic_cast。没有就用static_cast。


Reference