1,类型转换函数主要功能就是做类型转换,类型转换是将一个数据从 A 类型转换 到 B 类型,有隐式类型转换和强制类型转换两种;
2,再论类型转换:
1,标准数据类型之间会进行隐式的类型安全转换;
1,C 语言编译器只会在标准数据类型之间做转换,并且 C 编译器内置了些规则,遵循这些规则标准数据间可以进行隐式类型转换;
2,转换规则如下:
1,char( ==> short)==> int ==> unsigned int ==> long ==> unsigned long ==> float ==> double;
2,小类型转换到大类型是允许的,因为这样是安全的,且不会有警告;
3,有趣的隐式类型转换实例分析:
1,main.cpp 文件:
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; // 编译器将两个操作数都转换为 int 类型,编译器这样做的原因是因为编译器认为 4 个字节的运算是最高效的,编译器自认为安全、高效; 27 28 return 0; 29 }
2,输出结果:
1 d = -2000 2 ui = 1000 3 ui + i = 4294966296 4 Positive 5 sizeof(s + 'b') = 4
4,写代码时要尽量的避免隐式类型转换;
3,问题:
1,普通类型与类类型之间能否进行类型转换?类类型之间能否进行类型转换?
2,普通类型到类类型转换编程实验:
1,main.cpp 文件:
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 t = static_cast<Test>(5); // ==> t = Test(5); 从 C 语言角度,这里将 5 强制类型转换到 Test 类型,只不是编译器 在这里做了隐式类型转换,本质是调用转换构造函数; 38 39 Test r; 40 41 r = t + static_cast<Test>(10); // ==> r = t + Test(10); 如果工程上这行是手误,则编译器并不能发现这样的低级错误; 42 43 cout << r.value() << endl; 44 45 return 0; 46 }
4,再论构造函数:
1,构造函数可以定义不同类型的参数;
2,参数满足下列条件时称为转换构造函数:
1,有且仅有一个参数;
1,这个参数类型只要不是自己当前类型就可以;
2,参数是基本类型;
3,参数是其它类类型;
5,另个一视角,旧式的 C 方式强制类型转换:
1,代码示例:
1 int i; 2 Test t; 3 4 i = int(1.5); 5 t = Test(100); // 将整型数 100 强制类型转换到 Test 类类型,本质是调用构造函数;
6,编译器的行为:
1,编译器会尽力尝试让源码通过编译;
2,编译器尽力尝试的结果是隐式类型转换:
1,隐式类型转换:
1,会让程序以意想不到的方式进行工作;
2,是工程中 bug 的重要来源;
3,工程中通过 explicit 关键字杜绝编译器的转换尝试;
1,explicit,显示的;
4,转换构造函数被 explicti 修饰时只能进行显示转换;
1,显示转换方式:
1,static_cast<ClassName>(value);
1,这里有调用转换构造函数;
2,ClassName(value); // C++ 角度是手工调用构造函数;
1,这里有调用转换构造函数,实质就是调用构造函数;
3,(ClassName)value; // C++ 中不推荐;
1,这里有调用转换构造函数;
7,小结:
1,转换构造函数只有一个参数;
2,转换构造函数的参数类型是其他类型;
3,转换构造函数在类型转换时被调用;
1,无论是显示的还是隐式的,都会被调用;
4,隐式类型转换是工程中 bug 的重要来源;
5,explicit 关键字用于杜绝隐式类型转换;
1,如果不是故意的,更改;
2,如果想要故意的,手动显示类型转换;