Loading

【C++】C++之类型转换

作者:李春港
出处:https://www.cnblogs.com/lcgbk/p/14209848.html

一、前言

在C语言中,我们经常会对数据进行类型转换,但都是强制性的类型装换,自然就会引发访问不安全的问题,可能不经意间将指向const对象的指针转换成非const对象的指针,可能将基类对象指针转成了派生类对象的指针,这种转换很容易出bug,需要严格审查代码才能消除这种隐患,而且这种转换方式不利于我们审查代码,且程序运行时也可能会出bug,所以C++为了提高类型装换的安全性,关于类型转换引入了四种方式:static_cast、const_cast、dynamic_cast、reinterpret_cast,接下来看下其四种类型装换的应用场景。

二、static_cast

2.1 使用场景

基本数据类型之间的转换使用,例如float转int,int转char等,在有类型指针和void*之间转换使用,子类对象指针转换成父类对象指针也可以使用static_cast。

非多态类型转换一般都使用static_cast,而且最好把所有的隐式类型转换都是用static_cast进行显示替换,不能使用static_cast在有类型指针之间进行类型转换。

2.2 实例

#include <iostream>

using namespace std;

struct Base {
    virtual void Func() { cout << "Base Func \n"; }
};

struct Derive : public Base {
    void Func() override { cout << "Derive Func \n"; }
};

int main() 
{
    float f = 1.23;
    cout << "f " << f << endl;
    int i = static_cast<int>(f);
    cout << "i " << i << endl;

    void *p;
    int *i_p = static_cast<int *>(p);
    void *pi = static_cast<void *>(&f);
    int *pi = static_cast<int *>(&f);  // error invalid static_cast from type ‘float*’ to type ‘int*’

    Derive d;
    d.Func();
    Base *b = static_cast<Base *>(&d); 
    b->Func();
    return 0;
}

三、dynamic_cast

3.1 使用场景

用于将父类的指针或引用转换为子类的指针或引用,此场景下父类必须要有虚函数(只要拥有虚函数就行),因为dynamic_cast是运行时检查,检查需要运行时信息RTTI.如果不清楚什么是RTTI,可以去了解下C++的RTTI机制。

3.2 实例

#include <iostream>

using namespace std;

struct Base {
    virtual void Func() { cout << "Base Func \n"; }
};

struct Derive : public Base {
    void Func() override { cout << "Derive Func \n"; }
};

int main() {
    Derive d;
    d.Func();
    Base *b = dynamic_cast<Base *>(&d);
    b->Func();
    Derive *dd = dynamic_cast<Derive *>(b);
    dd->Func();
    return 0;
}

四、const_cast

4.1 使用场景

用于常量指针或引用与非常量指针或引用之间的转换,只有const_cast才可以对常量进行操作,一般都是用它来去除常量性,去除常量性是危险操作,还是要谨慎操作。

4.2 实例

int main() {
    int data = 10;
    const int *cpi = &data;

    int *pi = const_cast<int *>(cpi);

    const int *cpii = const_cast<const int *>(pi);
    return 0;
}

五、reinterpret_cast

5.1 使用场景

没啥场景,类似C语言中的强制类型转换,什么都可以转,万不得已不要使用,一般前三种转换方式不能解决问题了使用这种强制类型转换方式。

5.2 实例

int main() {
    int data = 10;
    int *pi = &data;

    float *fpi = reinterpret_cast<float *>(pi);

    return 0;
}

六、总结

方式 使用场景
static_cast 基本数据类型之间的转换使用,例如float转int,int转char等;子类对象指针转换成父类对象指针也可以使用static_cast;在有类型指针和void*之间转换使用,不能使用static_cast在有类型指针之间进行类型转换。
dynamic_cast 用于将父类的指针或引用转换为子类的指针或引用,此场景下父类必须要有虚函数(只要拥有虚函数就行)
const_cast 用于常量指针或引用与非常量指针或引用之间的转换。
reinterpret_cast 类似C语言中的强制类型转换,什么都可以转,尽量不要使用此方式。
posted @ 2020-12-30 09:35  李春港  阅读(476)  评论(0编辑  收藏  举报