C语言编译中类型转换:
C语言编译器只会在标准数据类型之间做转换。
隐式类型转换复习:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 int main() 7 { 8 short s = 'a'; 9 unsigned int ui = 1000; 10 int i = -2000; 11 double d = i; 12 13 cout << "d = " << d << endl; 14 cout << "ui = " << ui << endl; 15 cout << "ui + i = " << ui + i << endl; 16 17 if( (ui + i) > 0 ) 18 { 19 cout << "Positive" << endl; 20 } 21 else 22 { 23 cout << "Negative" << endl; 24 } 25 26 cout << "sizeof(s + 'b') = " << sizeof(s + 'b') << endl; 27 28 return 0; 29 }
结果如下:
第26行的s和'b'转换为int类型再相加。
问题:
示例程序:
编译结果如下:
可以看到这种普通类型到类类型的强制转换是不被允许的。
将程序更改如下:
这时就可以正常编译通过了。
再论构造函数:
只有一个参数,而且这个参数不是自己的当前类型,这就可以叫做转换构造函数。
另一个视角:
i = int(1.5)这时C语言中一种比较老旧的强制类型转换方法。
t = Test(100)就是将100强制转换为Test类型,本质是调用构造函数。
编译器的行为:
示例:
我们重载了+号操作符,这样的话44行会编译通过,编译器将10隐式类型转换为一个Test类对象,然后执行解法操作。
但是r = t + 10这一行有可能使我们手误写错了,我们不希望这样的程序编译通过。写错的程序编译通过可能会在运行时出现意想不到的现象,我们更希望在编译阶段能检查出来。
这时,我们需要将类型转换关掉,怎么具体操作呢?
上图中第1中类型转换是C++中推荐的转换方式。第2中转换方式可以认为是手工类型转换,也可以认为是手工调用构造函数。
程序如下:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 class Test 7 { 8 int mValue; 9 public: 10 Test() 11 { 12 mValue = 0; 13 } 14 15 explicit Test(int i) 16 { 17 mValue = i; 18 } 19 20 Test operator + (const Test& p) 21 { 22 Test ret(mValue + p.mValue); 23 24 return ret; 25 } 26 27 int value() 28 { 29 return mValue; 30 } 31 }; 32 33 int main() 34 { 35 Test t; 36 37 38 t = static_cast<Test>(5); // t = Test(5); 39 40 41 42 Test r; 43 44 r = t + static_cast<Test>(10); // r = t + Test(10); 45 46 cout << r.value() << endl; 47 48 return 0; 49 }
这时对于t = 5这样的程序编译器就会报错。编译器不会在进行隐式类型转换。
如果想通过编译,我们只能自己在程序中手工转换,如38、44行程序那样。
小结: