第41课.类型转换函数(上)

1.再论类型转换

a.标准数据类型之间会进行隐士类型安全转换
b.转换规则

问题1:

eg:

#include <iostream>
#include <string>

using namespace std;

int main()
{
    unsigned int ui = 1000;
    int i = -2000;
    
    cout << "i  = " << i << endl;
    cout << "ui = " << ui << endl;
    cout << "ui + i = " << ui + i << endl;    //注意这里不是-1000
    
    return 0;
}

再次测试:

ui = -1000          很大的数   
            ==>                ==>     1000
i  = 2000           2000
-------------------------------------------------
ui = 1000           1000 
            ==>                ==>     很大的数
i  = -2000          很大的数

结论:
unsigned intint相加时

unsigned int + int = 负数: 输出采用类似于c语言中的**%u**
unsigned int + int = 正数: 输出采用类似于c语言中的**%d**

问题2

eg:

#include <iostream>
#include <string>

using namespace std;

int main()
{
    short s = 'a';
    
    cout << "sizeof(s + 'b') = " << sizeof(s + 'b') << endl;

    return 0;
}

这里short + char理论上来说char应该隐式的转化为2字节的short,但是在实验中测试。两者都转换为了4字节的int,因为编译器这样做最高效。其他的就没有什么特殊的问题了。隐式转换没有什么问题。

2.再论构造函数(隐式转换的危害,基本类型->类类型)

a.构造函数可以定义不同类型的参数
b.参数满足下列条件时称为转换构造函数
 1).有且仅有一个参数
 2).参数是基本类型
 3).参数是其它类类型

编译器的行为

编译器会通过转换构造函数,隐式的实现类型的转换。本来是用来构造对象的,结果被用来做隐式的类型转换,这是bug的一个重要来源。

解决办法:

a.工程中通过explicit关键字杜绝编译器的转换尝试
b.转换构造函数被explicit修饰时只能进行显示的类型转换

推荐的转换方式:

static_cast<ClassName>(Value);

eg:

#include <iostream>
#include <string>

using namespace std;

class Test 
{
    int mValue;
public:
    Test ()
    {
        mValue = 0;
    }
    
    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;
 
 #if 0 
    t = 5;      // 5这个数默认类型为int, int怎么能赋值给t对象呢?编译器在这个时候,选择去查找转换构造函数。法想Test类中定义了Test (int i)这个转换构造函数。
                //此时编译器将原语句转换为 Test = Test(5);这时Test(5)产生一个临时对象。
    
    Test r;
    
    r = t + 10;     // t对象不能和int相加。此时调用隐式类型转换 t + Test(10);
                    // 这里就能看出bug了,本来是对象和对象的相加结果在这里对象和整形也能相加。
                    
#endif

    t = static_cast<Test>(5);        //static_cast也可以用于基本能类型和类类型的转换
    
    Test r;
    
    r = t + static_cast<Test>(10);
    
    cout << r.value() << endl;
    
    return 0;
}
posted @ 2019-11-23 16:19  人民广场的二道贩子  阅读(148)  评论(0编辑  收藏  举报