类型转换函数
-
论类型转换
-
标准数据类型之间会进行隐式的类型安全转换
-
转换规则如下所示:
char ===>int ==>unsigned int ==>long ==>unsigned long ==>float ==>double
|| ||
V ||
short===
-
例:
1 // 类型转换函数.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 2 // 3 #include <iostream> 4 #include <string> 5 using namespace std; 6 int main() 7 { 8 int a = -2000; 9 unsigned int b = 1000; 10 short c = 'A'; 11 cout << "sizeof(c+'B')=" << sizeof(c + 'B') << endl; 12 cout << "a+b=" << a + b << endl; 13 if ((a+b)>0) 14 { 15 cout << "Positive" << endl; 16 } 17 else 18 { 19 cout << "Nagitve" << endl; 20 } 21 }
运行结果:
sizeof(c+'B')=4
a+b=4294966296
Positive
从程序的运行结果来看,我们会发现两个问题
问题1:sizeof(c+'B')结果为什么为4,不应该是两个字节吗?
问题2:从数学的角度看,-2000+1000不应该是-1000吗?为什么结果为正?
答1:c的类型为short类型,占两个字节,程序在编译时将'A'优化隐式类型转换为short类型
答2::a的类型为int类型,程序在编译时会将其隐式转换成unsigned int类型
请看下面的程序:
1 // 类型转换函数.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 2 // 3 #include <iostream> 4 #include <string> 5 using namespace std; 6 class Test 7 { 8 int mvalue; 9 public: 10 Test() 11 { 12 mvalue = 0; 13 } 14 Test(int i) 15 { 16 mvalue = i; 17 } 18 Test operator +(const Test& obj) 19 { 20 Test ret(mvalue+obj.mvalue); 21 return ret; 22 } 23 int get_value() 24 { 25 return mvalue; 26 } 27 }; 28 int main() 29 { 30 Test t(5); 31 cout << "t.mvalue=" << t.get_value() << endl; 32 t = 10; 33 cout << "t.mvalue=" << t.get_value() << endl; 34 }
t=10;这条语句,会发现一个问题,10为整型数据,它怎么可以给一个对象赋值呢?更加诡异的是,编译竟然通过,且可以正常运行!
再论构造函数
-
构造函数可以定义不同类型的参数
-
参数满足下列条件时称为转换构造函数
-
有且仅有一个参数
-
参数是基本类型
-
参数是其它类类型
从另一个视角看:
-
旧式的C方式强制类型转换
int i; Test t; i = int(1.5); t = Test(100);
编译器是怎么看待t=10呢??
“10这个立即数默认为int类型,怎么可能赋值给t对象呢!现在就报错吗?不急,我看看有没有转换构造函数!OK,发现Test类中定义了Test(int i),可以进行转换,默认等价于:t = Test(100);"
-
编译器的行为
-
编译器尽力尝试的结果是隐式类型转换
-
隐式类型转换会让程序以意想不到的方式进行工作,是工程中bug的重要来源。
-
在工程中通过explicit关键字杜绝编译器的转换尝试
-
转换构造函数被explicit修饰时只能进行显示转换
-
转换方式
-
static_cast<ClassName>(value);
-
ClassName(value);
-
(ClassName)value; //不推荐
进行强制类型转换,正确写法如下:
// 类型转换函数.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include <iostream> #include <string> using namespace std; class Test { int mvalue; public: Test() { mvalue = 0; } explicit Test(int i) { mvalue = i; } Test operator +(const Test& obj) { Test ret(mvalue+obj.mvalue); return ret; } int get_value() { return mvalue; } }; int main() { Test t(5); cout << "t.mvalue=" << t.get_value() << endl; t =static_cast<Test>(10); cout << "t.mvalue=" << t.get_value() << endl; }
思考:类类型是否能够类型转换到普通类型??
类型转换函数
-
C++类中可以定义类型转换函数
-
类型转换函数用于将类对象转换为其它类型
-
语法规则:
operator Type() { Type ret; //.... return ret; }
例:
// 类型转换函数.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include <iostream> #include <string> using namespace std; class Test { int mvalue; public: Test() { mvalue = 0; } //转换构造函数 explicit Test(int i) { mvalue = i; } //类型转换函数 operator int() { int ret; ret = mvalue; return ret; } Test operator +(const Test& obj) { Test ret(mvalue+obj.mvalue); return ret; } int get_value() { return mvalue; } }; int main() { Test t(5); cout << "t.mvalue=" << t.get_value() << endl; t =static_cast<Test>(10); cout << "t.mvalue=" << t.get_value() << endl; int i = t; cout << "i=" << i << endl; }
-
类型转换函数
-
与转换构造函数具有同等的地位
-
使得编译器有能力将对象转化为其它类型
-
编译器能够隐式的使用类型转换函数
-
编译器会尽力尝试让源码通过编译( int i = t;)
“t这个对象为Test类型,怎么可能用于初始化int类型的变量呢!现在就报错吗不急,我看看有没有类型转换函数!OK,发现了Test类中定义了operator int(),可以进行转换”
-
类类型之间的相互转换(类型转换函数VS转换构造函数)
-
无法抑制隐式的类型转换函数调用
-
类型转换函数可能与转换构造函数冲突
-
工程中Type to Type的公有成员代替类型转换函数
// 类型转换函数.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include <iostream> #include <string> using namespace std; class value { int _val; public: value() { _val = 0; } value(int i) { _val = i; } int get_value() { return _val; } }; class Test { int mvalue; public: Test() { mvalue = 0; } //转换构造函数 explicit Test(int i) { mvalue = i; } //类型转换函数 operator int() { int ret; ret = mvalue; return ret; } //类类型之间的转换 operator value() { value ret(mvalue); return ret; } Test operator +(const Test& obj) { Test ret(mvalue+obj.mvalue); return ret; } int get_value() { return mvalue; } }; int main() { Test t(5); value v(9); cout << "t.mvalue=" << t.get_value() << endl; t =static_cast<Test>(100); cout << "t.mvalue=" << t.get_value() << endl; int i = t; cout << "i=" << i << endl; //类类型之间的转换 v = t; cout << "v._val=" << v.get_value() << endl; }
运行结果:
t.mvalue=5
t.mvalue=100
i=100
v._val=100
使用Type toType()的公有成员代替类型转换函数
// 类型转换函数.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include <iostream> #include <string> using namespace std; class Test; class value { int _val; public: value() { _val = 0; } value(int i) { _val = i; } int get_value() { return _val; } }; class Test { int mvalue; public: Test() { mvalue = 0; } //转换构造函数 explicit Test(int i) { mvalue = i; } //类型转换函数 operator int() { int ret; ret = mvalue; return ret; } //类类型之间的转换 operator value() { value ret(mvalue); return ret; } //使用Type toType()来代替类型转换函数 int toINT() { int ret; ret = mvalue; return ret; } Test operator +(const Test& obj) { Test ret(mvalue + obj.mvalue); return ret; } int get_value() { return mvalue; } }; int main() { Test t(5); value v(9); cout << "t.mvalue=" << t.get_value() << endl; t =static_cast<Test>(100); cout << "t.mvalue=" << t.get_value() << endl; int i = t; cout << "i=" << i << endl; //类类型之间的转换 v = t; cout << "v._val=" << v.get_value() << endl; //使用类中的公有成员函数进行类型转换 int x = t.toINT(); cout << "x=" << x << endl; }
运行结果:
t.mvalue=5
t.mvalue=100
i=100
v._val=100
x=100
小结:
-
转换构造函数只有一个参数
-
转换构造函数的参数类型是其它类型
-
转换构造函数在类型转换时被调用
-
隐式类型转换是工程中bug的重要来源
-
explicit关键字用于杜绝隐式类型转换
-
C++类中可以定义类型转换函数
-
类型转换函数用于将类对象转换为其它类型
-
类型转换函数与转换构造函数具有同等的地位
-
工程中以Type toType()的公有成员代替类型转换函数
主要记录的是学习听课的笔记