Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C++转型对比 #34

Open
guodongxiaren opened this issue Apr 6, 2020 · 0 comments
Open

C++转型对比 #34

guodongxiaren opened this issue Apr 6, 2020 · 0 comments
Assignees
Labels
C/C++ 兵中凶兽 C++

Comments

@guodongxiaren
Copy link
Owner

从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。


Reference

@guodongxiaren guodongxiaren added the C/C++ 兵中凶兽 C++ label Apr 6, 2020
@guodongxiaren guodongxiaren self-assigned this Apr 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C/C++ 兵中凶兽 C++
Projects
None yet
Development

No branches or pull requests

1 participant