第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关键字用于杜绝编译器这种隐式类型转换的行为

 

posted @ 2018-12-23 23:43  梦心之魂  阅读(145)  评论(0编辑  收藏  举报