• 第41课


    1. 再论类型转换

    (1)标准数据类型之间会进行隐式类型安全转换

    (2)转换规则

          

    【实例分析】有趣的隐式类型转换   41-1.cpp

    #include <iostream>
    
     
    
    using namespace std;
    
     
    
    int main()
    {
    
        short s ='a';
    
        unsigned int ui = 1000;
    
        int i = -2000;
    
        double d = i;
    
       
    
        cout << "d = " << d << endl;   //d = -2000
    
        cout << "ui = " << ui << endl; //ui = 1000;
    
        cout << "ui + i = " << ui + i << endl; //ui + i = 4294966296i。
    
                                               //因为i会被转为unsigned int类型,
    
                                               //变成一个很大的正数。
    
        if ((ui + i) > 0) 
    
            cout << "Positive" << endl; //该行被输出,因为ui+i变成一个很大的正数
    
        else
    
            cout << "Negative" << endl; //负数
    
     
    
        //根据标准数据类型的转换规则s->int。'b'为char,也会被转为int型。所以输出4
        cout << "sizeof(s + 'b') = " << sizeof(s + 'b') << endl;   //输出4,即两个int类型相加
    
       
    
        return 0;
    
    }

    运行结果:

      

    2. 普通类型类类型的转换——转换构造函数

    (1)构造函数可以定义不同类型的参数

    (2)参数满足下列条件时称为转换构造函数

      ①有且仅有一个参数

      ②参数基本类型

      ③参数其它类类型但不是本类的const引用,因为那叫拷贝构造函数

    (3)另一个视角:旧式的C方式强制类型转换

    int i = int(1.5);   //将浮点转为整型,有点像函数调用
    
    Test t;
    t = Test(
    100); //老旧的C转换方式,有点像函数调用

    3. explicit关键字

    1)编译器隐式转换行为:

      ①编译器尽力尝试让源码通过编译

    Test t;
    
    t = 100;  //100这个立即数,默认为int型,怎么可能赋值给t对象呢?现在就报错
    
              //吗?不急,编译器会看看有没有转换构造函数!Ok,发现Test类中定义
    
              //Test(int i),可以进行转换,默认等价于:t = Test(100);

      ②隐式类型转换会让程序以意想不到的方式进行工作,是工程中Bug的重要来源

    (2)杜绝编译器的隐式类型转换explicit关键字

      ①用explicit修饰转换构造函数。这时会阻止编译器隐式地尝试调用这个函数的行为

      ②当转换构造函数explicit修饰时,只能手动进行显式的转换转换方式:

      • A.static_cast<ClassName>(value);

      • B.ClassName(value);

      • C.(ClassName)value;    //不推荐

    【编程实验】普通类型→类类型   41-2.cpp

    #include <iostream>
    
    
    
    using namespace std;
    
    
    
    class Test
    {
    
        int mValue;
    
    public:
    
        Test(){mValue = 0;}
    
    
    
        explicit Test(int i) //转换构造函数
        {
    
            mValue = i;
    
        }
    
    
    
        Test operator + (const Test& p)
        {
    
            Test ret(mValue + p.mValue);
    
    
    
            return ret;
    
        }
    
    
    
        int value()
        {
    
            return mValue;
    
        }
    
    };
    
    
    
    int main()
    {
    
        Test t;
    
        //t = 5; //会报错,将5赋值给t对象,编译器会尝试调用Test(int i)转换构造函数
    
                 //但由于Test(int i)前面用explicit修饰,以后拒绝了这种尝试。所以
    
                 //编译不通过。
    
        t = static_cast<Test>(5); //相当于 t = Test(5); 原因:Test(int i)被explicit修饰,
    
                                  //就是告诉编译器要阻止那种通过隐式调用该函数的行为发生。
    
                                  //只有显式调用Test(int i)(或通过强制类型方式转换的)
    
                                  //才允许调用这个函数来进行类型的转换。
    
    
    
        Test r;
    
        //r = t + 10;//相当于:r = t + Test(10);
    
        r = t + static_cast<Test>(10);
    
        cout << r.value() << endl; //15;
    
        return 0;
    
    } 

    运行结果:

      

    4. 小结

    (1)转换构造函数只有一个参数

    (2)转换构造函数参数类型其它类型

    (3)转换构造函数类型转换被调用

    (4)隐式类型转换工程中Bug的重要来源

    (5)explicit关键字用于杜绝编译器这种隐式类型转换的行为

  • 相关阅读:
    c++标准库容器【转】
    C++命名空间的解释 【转】
    [转载]定义、公理、定理、推论、命题和引理的区别
    待读论文
    矩阵分解 Matrix Factorization (RegularSVD) 实验总结
    Predicting the Next Location: A Recurrent Model with Spatial and Temporal Contexts AAAI2016
    Discovering Urban Functional Zones Using Latent Activity Trajectories TKDE 2015
    numpy
    python 编程 规范
    深度学习
  • 原文地址:https://www.cnblogs.com/hoiday/p/10166499.html
Copyright © 2020-2023  润新知