普通类型和类类型之间的转换
1.普通类型——>类类型
问题:假如把一个 int 类型转换为 类类型,有什么办法呢?
下面的直接转换是错误的:
#include <iostream>
using namespace std;
class Test
{
};
int main()
{
Test t1;
t1 = -5; //注意这里
return 0;
}
小贴士:
对于Test类,其中包含4个默认函数:
默认构造函数 + 默认拷贝构造函数 + 默认赋值构造函数 +析构函数
结论:
- 编译器不支持普通类型到类类型的直接转换
【新概念】
转换构造函数
- 本身是构造函数
- 只有一个形参
- 参数类型不是自身类型
#include <iostream>
using namespace std;
class Test
{
private:
int mValue;
public:
Test():mValue(0)
{
}
Test(int i)
{
mValue = i;
}
int value()
{
return mValue;
}
~Test()
{
}
};
int main()
{
Test t;
t = 5; // 注意这里!
cout << "t.value() = " << t.value() << endl;
return 0;
}
- t = 5; ==> t = Test(5);
- 产生临时对象来初始化 t
- 编译器会尽力尝试进行隐式类型转换
- 是 Bug 的重要来源
- 编译器会尽力尝试进行隐式类型转换
explicit 关键字
- 工程中使用 explicit 关键字杜绝编译器的尝试性转换
- 转换构造函数被 explicit 修饰后只能进行显示转换
- 转换方式
- static_cast(value); (C++推荐)
- ClassName(value); (C++方式)
- (ClassName) value; (C语言风格)
- 转换方式
class Test
{
private:
int mValue;
public:
Test():mValue(0)
{
}
explicit Test(int i) //注意这里
{
mValue = i;
}
int value()
{
return mValue;
}
~Test()
{
}
};
-
Test(int i) 被 explicit 修饰后,只能进行显示调用构造函数
-
Test t; t = static_cast<Test>(5); //显示调用
-
会生成临时对象初始化 t
2. 类类型——>普通类型
【思考】类类型实质就相当于C语言的结构体,是多种类型的集合,普通类型只是一种类型,可以实现类到普通类型的转换吗?
#include <iostream>
using namespace std;
class Test
{
};
int main()
{
Test t;
int i = 100;
i = (int)t;
return 0;
}
结果:
- 编译直接报错,不能实现’Test’到’int’类型的转换
类型转换函数
【新概念】
类型转换函数
-
C++ 类可以定义类型转换函数
-
类型转换函数用于实现 类类型——>其他类型 直接的转换
-
语法规则
-
operator Type () { Type ret; // ... return ret; }
-
测试:
#include <iostream>
using namespace std;
class Test
{
private:
int mValue;
public:
Test(int i)
{
mValue = i;
}
int value()
{
return mValue;
}
operator int () //注意这里
{
return mValue;
}
};
int main()
{
Test t(-5);
int i = t; // ==>int i = t.operator int ();
cout << "t.value() = " << t.value() << endl;
cout << "i = " << i << endl;
return 0;
}
输出:
t.value() = -5
i = -5
【小贴士】
- 类型转换函数与转换构造函数有相同的地位
- 类型转换函数使得编译器可以将类对象转化为其他类型对象
- 编译器可以隐式使用类型转换函数
类类型之间的转换
【小思考】类型转换函数可以实现类 类型到其他类型的转换,那么其他类类型也属于其他类型,比如类A可以准换到类B吗?
#include <iostream>
using namespace std;
class Test;
class Value
{
public:
Value()
{
}
};
class Test
{
public:
operator Value ()
{
Value ret;
return ret;
}
};
int main()
{
Test t;
Value v = t; // <==> Value v = t.operator Value ();
return 0;
}
- 类型转换函数确实可以实现 不同类类型之间的转换
【小疑问】转换构造函数可以实现其他类型到类类型之间的转换,那么可以实现类A 到 类B 之间的转换吗?
#include <iostream>
using namespace std;
class Test;
class Value
{
public:
Value()
{
}
Value(Test& t)
{
}
};
class Test
{
};
int main()
{
Test t;
Value v = t; //==>Value v = value(t);
return 0;
}
- 转换构造函数是可以实现 类类型之间的转换
-
类型转换函数与转换构造函数可能产生冲突
-
类型转换函数的隐式调用无法抑制
-
工程中使用 Type toType()的公有成员函数代替类型转换函数
#include <iostream> using namespace std; class Test; class Value { public: Value() { } explicit Value(Test& t) //不能隐式调用 { } }; class Test { public: Value toValue () // 注意这里 { Value ret; cout << "operator Value ()" << endl; return ret; } }; int main() { Test t; Value v = t.toValue(); return 0; }
这里才恍然大悟:原来java 和 Qt 里面的str.toInt()的起源在这里。