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

1.再论类型转换

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

问题1:

eg:

include

include

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

include

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(Value);
eg:

include

include

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(5); //static_cast也可以用于基本能类型和类类型的转换

Test r;

r = t + static_cast(10);

cout << r.value() << endl;

return 0;
}

posted @ 2019-11-23 16:19  人民广场的二道贩子  阅读(176)  评论(0)    收藏  举报