1. 隐式类型转换规则
编译器的默认隐式类型转换规则:
先看个例子:
short s = 'a';
unsigned int ui = 1000;
int i = -2000;
double d = i;
//自己先想一下输出结果,会是什么
cout << "d = " << d << endl;
cout << "ui + i = " << ui + i << endl;
cout << "sizeof(s + 'b') = " << sizeof(s + 'b') <<endl;
编译运行结果:
d = -2000
ui + i = 1000
sizeof(s + 'b') = 4
为什么会是这样??? 为什么不是 ui + i = -1000
因为编译器做了隐式类型转换。
看明白了吗?那想必你也就明白了为什么sizeof(s + ‘b’) = 4 了吧。
2. 转换构造函数:
构成:(1)、首先是一个类的构造函数
(2)、有且仅有一个参数
(3)、参数类型是 基本类型 或者 其他类类型
转换:
相当于C语言风格中的隐式类型转换,比如:
int i = 1.5; //就是隐式转化成了i = (int)1
所以这里的类Test t = 100; // 就是t = Test(100);
#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;
t = 5; // t = Test(5);
Test r;
r = t + 10; // r = t + Test(10);
cout << "r.value() = " << r.value() << endl;
return 0;
}
猜一下能编译通过吗?如果能通过,运行结果是多少?
编译运行结果:
r.value() = 15
为了避免隐式转换带来bug,所以在项目中通常使用关键字explicit杜绝编译器的隐式转化,转换构造函数被explicit修饰时只能进行显示转换。
3. 类型转换函数
现在我们来想一个问题, 一个基础数据类型 和 类类型 之间能不能进行相互转换?两个类类型之间能不能进行相互转换?
示例1:
#include <iostream>
#include <string>
using namespace std;
class Test
{
int mValue;
public:
Test(int i = 0)
{
mValue = i;
}
int value()
{
return mValue;
}
operator int () // 重载int类型转换函数
{
return mValue;
}
};
int main()
{
Test t(100);
int i = t; // 把一个类类型赋值给一个int类型
cout << "t.value() = " << t.value() << endl;
cout << "i = " << i << endl;
return 0;
}
示例2:
#include <iostream>
#include <string>
using namespace std;
class Test;
class Value
{
public:
Value()
{
}
explicit Value(Test& t) // 有explicit关键字修饰的转换构造函数,使用时需要显式调用
{
}
};
class Test
{
int mValue;
public:
Test(int i = 0)
{
mValue = i;
}
int value()
{
return mValue;
}
operator Value() // 重载Value类类型
{
Value ret;
cout << "operator Value()" << endl;
return ret;
}
};
int main()
{
Test t(100);
Value v = t;
return 0;
}
因为无法抑制隐式的类型转换函数调用,或者类型转换函数可能与转换构造函数冲突,所以在项目中通常使用Type toType()
的共有成员函数代替类型转换函数。