C++ 类型转换(23)

2022-06-30  本文已影响0人  maskerII

一、前言

类型转换(cast)是将一种数据类型转换成另一种数据类型。例如,如果将一个整型值赋给一个浮点类型的变量,编译器会暗地里将其转换成浮点类型。

转换是非常有用的,但是它也会带来一些问题,比如在转换指针时,我们很可能将其转换成一个比它更大的类型,但这可能会破坏其他的数据。

应该小心类型转换,因为转换也就相当于对编译器说:忘记类型检查,把它看做其他的类型。

一般情况下,尽量少的去使用类型转换,除非用来解决非常特殊的问题。

标准c++提供了一个显示的转换的语法,来替代旧的C风格的类型转换。

使用C风格的强制转换可以把想要的任何东西转换成我们需要的类型。那为什么还需要一个新的C++类型的强制转换呢?

新类型的强制转换可以提供更好的控制强制转换过程,允许控制各种不同种类的强制转换。C++风格的强制转换其他的好处是,它们能更清晰的表明它们要干什么。程序员只要扫一眼这样的代码,就能立即知道一个强制转换的目的。

二、静态转换 static_cast

2.1 基础类型 转换

// 1. 基础类型 转换
void test01()
{
    char a = 'a';
    // char->double
    // static_cast<要转到的类型>(需要将谁转换)
    double d = static_cast<double>(a);

    double d1 = (double)a;

    cout << d << "   " << d1 << endl;
}

2.2 有层次关系类的指针或引用 转换

// 2.有层次关系类的指针或引用 转换
class Father
{

};

class Son:public Father
{

};

class Other
{

};

// 指针转换
void test02() {
    Father *f = NULL;
    Son *s = NULL;

    // 向上转换 安全
    Father *f1 = static_cast<Father*>(s);
    // 向下转换 不安全
    Son *s1 = static_cast<Son*>(f);
    // 没有继承关系的类之间的指针不能转换 报错
    // Other *other = static_cast<Other *>(f); Err


}

// 引用转换
void test03() {
    Father f;
    Son s;
    Father &ref_f = f;
    Son &ref_s = s;
    // 向上转换 安全
    static_cast<Father &>(ref_s);
    // 向下转换 不安全
    static_cast<Son &>(ref_f);
}

三、动态转换 dynamic_cast

dynamic_cast 主要用于类层次间的上行转换和下行转换

在类层次间上线转换时,dynamic_cast和static_cast的效果是一样的,但在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全

// 动态转换 dynamic_cast
void test04() {
   // char a = 'a';
   // dynamic_cast<double>(a);  基础类型不能使用动态转换dynamic_cast

   Father *f = NULL;
   Son *s = NULL;
   // 向上转换,安全
   Father *f1 = dynamic_cast<Father *>(s);
   // 向下转换,不安全,会去检查 报错
   // Son *s1 = dynamic_cast<Son *>(f);

}

// 发生多态,向下转换,动态转换不报错
class Father2
{
public:
    virtual void func(){
        
    }
};

class Son2: public Father2
{
public:
    virtual void func(){
        
    }   

};

void test05() {
    Father2 *f = new Son2;
    // 向下转换
    dynamic_cast<Son2 *>(f);

}

四、常量转换const_cast

常量指针被转化为非常量指针,并且仍然指向原来对象
常量引用被转化为非常量引用,并且仍然指向原来对象
注意:不能直接对非指针或非引用的变量进行const_cast操作符去直接移除它的const

// 常量转换const_cast
void test06() {
    const int *p = NULL;
    // const -> 不带const
    int *newP = const_cast<int *>(p);

    int *pp = NULL;
    const int* newPP = const_cast<const int *>(pp);


    int a = 10;
    int &ref_a = a;
    const int &ref_a1 = const_cast<const int &>(ref_a);
    cout << ref_a1 << endl;

    int b = 20;
    const int &ref_b = b;
    int& ref_b1 =  const_cast<int &>(ref_b);
    cout << ref_b1 << endl;

}

五、重新解释转换(reinterpret_cast)

重新解释转换(reinterpret_cast) 不安全
主要用于将一种数据类型从一种类型转换为另一种类型
它可以将一个指针转成一个整数,也可以将一个整数转成一个指针

// 重新解释转换(reinterpret_cast) 
class Father
{

};

class Other
{

};

void test07() {
    int a = 10;
    int *p = reinterpret_cast<int *>(a);
    cout << p << endl;

    Father *f = NULL;
    Other *o = reinterpret_cast<Other *>(f);
}

https://gitee.com/msmasker/c--study/tree/master/code/day08

上一篇下一篇

猜你喜欢

热点阅读