---- 整理自狄泰软件唐佐林老师课程
文章目录
1. 再论类型转换
- 标准数据类型之间会进行 隐式的 类型安全转换
- 转换规则如下:
1.1 实例分析
#include <iostream>
#include <string>
using namespace std;
int main()
{
short s = 'a';
char c = 'c';
int i = -2000;
unsigned int ui = 1000;
double d = i;
cout << "d = " << d << endl;
cout << "ui = " << ui << endl;
cout << "ui + i = " << ui + i << endl; // uint + int --> uint + uint
if( (ui + i) > 0 )
{
cout << "Positive" << endl;
}
else
{
cout << "Negative" << endl;
}
cout << "sizeof(s + c) = " << sizeof(s + c) << endl; // short + char --> int + int 编译器为了高效 char --> int, short --> int
return 0;
}
1.2 问题
- 普通类型与类类型之间能否进行类型转换?
- 类类型之间能否进行类型转换?
2. 问题一:普通类型 & 类类型
2.1 编程实验:普通类型 & 类类型
#include <iostream>
#include <string>
using namespace std;
class Test
{
int mi;
public:
Test() {}
Test(int i) {
mi = i;
}
int value() {
return mi;
}
};
int main()
{
Test t;
cout << "t.mi = " << t.value() << endl;
t = 5; // 转换构造函数
// 5 默认为 int,通过转换构造函数 Test(int i) 进行转换
// --> t = Test(5);
cout << "t.mi = " << t.value() << endl;
return 0;
}
2.2 再论构造函数
- 构造函数可以定义不同类型的参数
- 参数满足下列条件时称为 转换构造函数
- 有且仅有一个参数
- 参数是 基本类型
- 参数是 其它类类型
2.3 旧式的 C 方式强制类型转换
2.4 编译器的行为
- 编译器会尽力尝试让源码通过编译
Test t;
t = 100;
- 编译器尽力尝试的结果是 隐式类型转换
#include <iostream>
#include <string>
using namespace std;
class Test
{
int mValue;
public:
Test() {}
Test(int i) {
mValue = i;
}
Test operator+(const Test& t) {
Test ret(mValue + t.mValue);
return ret;
}
int value() {
return mValue;
}
};
int main()
{
Test t;
t = 5; // 转换构造函数
// 5 默认为 int,通过转换构造函数 Test(int i) 进行转换
// --> t = Test(5);
Test r;
r = t + 10; // 隐式转换 Test + int --> Test + Test(10)
// 可能引入 bug,可能是手误,本意并不是如此,但是编译不报错
cout << "r.mValue = " << r.value() << endl;
return 0;
}
- 隐式类型转换:
- 会让程序以意想不到的方式进行工作
- 是工程中 bug 的重要来源
- 工程中通过 explicit 关键字 杜绝编译器的转换尝试
- 转换构造函数 被 explicit 修饰时只能进行 显示转换
#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& t) {
Test ret(mValue + t.mValue);
return ret;
}
int value() {
return mValue;
}
};
int main()
{
Test t;
t = 5;
Test r;
r = t + 10;
cout << "r.mValue = " << r.value() << endl;
return 0;
}
#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& t) {
Test ret(mValue + t.mValue);
return ret;
}
int value() {
return mValue;
}
};
int main()
{
Test t;
t = static_cast<Test>(5); // --> t = Test(5)
Test r;
r = t + static_cast<Test>(10); // --> r = t + Test(10)
cout << "r.mValue = " << r.value() << endl;
return 0;
}
- 转换方式:
static_cast<ClassName>(value);
ClassName(value);
(ClassName)value; // 不推荐
3. 问题二:类类型
- 类类型是否能够类型转换到普通类型?
- - NO
#include <iostream>
#include <string>
using namespace std;
class Test
{
};
int main()
{
Test t;
int i = t;
return 0;
}
3.1 类型转换函数
- C++ 类中可以定义 类型转换函数
- 类型转换函数 用于将 类对象 转换为 其它类型
- 语法规则:
3.2 编程实验:类型转换函数初探
#include <iostream>
#include <string>
using namespace std;
class Test
{
int mValue;
public:
Test(int i = 0) {
mValue = i;
}
int value() {
return mValue;
}
operator int() { // 类型转换函数
return mValue;
}
};
int main()
{
Test t(100);
int i = t;
cout << "t.mValue = " << t.value() << endl;
cout << "i = " << i << endl;
return 0;
}
#include <iostream>
#include <string>
using namespace std;
class Test
{
int mValue;
public:
Test(int i = 0) {
mValue = i;
}
int value() {
return mValue;
}
operator int() { // 类型转换函数
return mValue;
}
};
int main()
{
Test t(100);
// int i = t; 其实等价于
int i = t.operator int();
cout << "t.mValue = " << t.value() << endl;
cout << "i = " << i << endl;
return 0;
}
3.3 类型转换函数
- 与转换构造函数具有同等的地位
- 使得编译器 有能力将 对象 转化为 其它类型
- 编译器能够 隐式的使用类型转换函数
3.4 编译器的行为
- 编译器会尽力尝试让源码通过编译
Test t(1);
int i = t;
3.5 编程实验:类类型之间的转换
- 类类型之间的相互转换
- 类型转换函数 VS 转换构造函数
#include <iostream>
#include <string>
using namespace std;
class Test;
class Value
{
public:
Value()
{
}
explicit Value(Test& t)
{
}
};
class Test
{
int mValue;
public:
Test(int i = 0)
{
mValue = i;
}
int value()
{
return mValue;
}
operator Value()
{
Value ret;
cout << "operator Value()" << endl;
return ret;
}
};
int main()
{
Test t(100);
Value v = t;
return 0;
}
3.5.1 通过类型转换函数
#include <iostream>
#include <string>
using namespace std;
class Demo
{
public:
Demo() {}
};
class Test
{
int mValue;
public:
Test(int i = 0) {
mValue = i;
}
int value() {
return mValue;
}
operator Demo() { // 类型转换函数
Demo ret;
cout << "operator Demo()" << endl;
return ret;
}
};
int main()
{
Test t(100);
Demo v = t; // 等价于 Demo v = t.operator Demo();
return 0;
}
3.5.2 通过转换构造函数
#include <iostream>
#include <string>
using namespace std;
class Test; // Demo 中先使用了 Test 类型,需要先声明
class Demo
{
public:
Demo() {
}
Demo(Test& t) { // 转换构造函数
}
};
class Test
{
int mValue;
public:
Test(int i = 0) {
mValue = i;
}
int value() {
return mValue;
}
/*
operator Demo() { // 类型转换函数
Demo ret;
cout << "operator Demo()" << endl;
return ret;
}
*/
};
int main()
{
Test t(100);
Demo v = t; // 等价于 Demo v = Demo(t);
return 0;
}
3.5.3 类型转换函数可能与转换构造函数冲突
#include <iostream>
#include <string>
using namespace std;
class Test; // Demo 中先使用了 Test 类型,需要先声明
class Demo
{
public:
Demo() {
}
Demo(Test& t) { // 转换构造函数
}
};
class Test
{
int mValue;
public:
Test(int i = 0) {
mValue = i;
}
int value() {
return mValue;
}
operator Demo() { // 类型转换函数
Demo ret;
cout << "operator Demo()" << endl;
return ret;
}
};
int main()
{
Test t(100);
Demo v = t;
return 0;
}
3.6 注意
- 无法抑制隐式的类型转换函数调用
- 类型转换函数可能与转换构造函数冲突
- 工程中以
Type toType()
的公有成员代替类型转换函数
#include <iostream>
#include <string>
using namespace std;
class Test; // Demo 中先使用了 Test 类型,需要先声明
class Demo
{
public:
Demo() {
}
explicit Demo(Test& t) { // 转换构造函数,explicit 必须显示转换
}
};
class Test
{
int mValue;
public:
Test(int i = 0) {
mValue = i;
}
int value() {
return mValue;
}
Demo toDemo() {
Demo ret;
cout << "Demo toDemo()" << endl;
return ret;
}
};
int main()
{
Test t(100);
Demo v = t.toDemo();
return 0;
}
4. 小结
- C++ 类中可以定义类型转换函数
- 类型转换函数用于将类对象转换为其它类型
- 类型转换函数与转换构造函数具有同等的地位
- 工程中以
Type toType()
的公有成员代替了类型转换函数