内置类型的转换:
内置类型之间的转换之前提过。相同类型的赋值直接进行,但不同类型之间的赋值系统会将将其转换成临时变量,这个临时变量具有常性,然后再将这个临时变量进行赋值,这里就不做代码演示了。自定义类型转换为内置类型暂时先不做考虑,后面深入文章会进行深入讲解。
这里要说明的是这里也不是什么内置类型都可以进行转换,当两个不同类型之间相似度较小时可以发生,当相差较大时就可能会报错。如:double与int之间相似度较大,可以发生;int与int*相似度就较小,可能会报错。如下:
int* ptr = nullptr;
int a = ptr;//出错double d = 1.2;
int x = d;//转换成功
自定义类型的转换:
自定义类型的隐式转换其实发生在构造函数中,构造函数不仅可以构造与初始化对象,对于单个参数或者除第一个参数无默认值其余均有默认值的构造函数,还具有类型转换的作用。
自定义类型与自定义类型之间相当于直接赋值运算,内置类型直接赋值自定义类型之间会发生隐式转换,即内置类型对象隐式转换成自定义类型对象。其中能支持这个转换,是因为有自定义类型的int单参数构造函数(支持传一个参数多参数带缺省也可以)支持。
当发生一个参数多参数带缺省的情况时,隐式转换默认自定义类型成员的第一个参数进行转换。我们也可多个内置类型赋值转换。这些转换其实跟调用构造函数的效果相同。
当内置类型向自定义类型中的内置类型发生转换时,会根据内置类型转内置类型的原则进行。
代码演练一:(单参构造函数)
#include <iostream>
using namespace std;
class A
{
public:A(int a):_a(a){ }void Print() {cout << _a << endl;}
private:int _a;
};
int main()
{A x1 = 5;//隐式类型转换为自定义类型对象x1.Print();//输出5
}
代码演练二:(多参数带缺省)
#include <iostream>
using namespace std;
class Date
{
public:Date(int year = 2023, int month = 10, int day = 16): _year(year), _month(month), _day(day){ }void Print() {cout << _year << "/" << _month << "/" << _day << endl;}
private:int _year;int _month;int _day;
};
int main()
{//单个隐式转换Date d1 = 5;//Date d1(5)的效果与之一样//多个隐式转换Date d2 = { 1,2,3 };//Date d2(1,2,3)的效果与之一样//括号表达式的运用Date d3 = (1, 2, 3);//等价于 Date d2 = 3;d1.Print();//输出5/10/16,属于单个隐式转换d2.Print();//输出1/2/3,属于多个隐式转换d3.Print();return 0;
}
explicit关键字:
explicit关键字可以防止自定义类型中构造函数的隐式类型转换。因为自定义类型的隐式转换发生在构造函数中,所以只需用 explicit 修饰构造函数防止这种转换。
class Date
{
public:
explicit Date(int year = 2023, int month = 10, int day = 16)
: _year(year)
, _month(month)
, _day(day)
{ }
private:
int _year;
int _month;
int _day;
};
int main()
{
//有了关键字explicit,下面的转换都不能实现
//Date d1 = 5;
//Date d2 = { 1,2,3 };
//Date d3 = (1, 2, 3);
Date d1(5);//类似于此种的方式没有设计隐式类型的转换,可以使用
return 0;
}
强制类型转换:
强制类型转换的效果比较强,explicit关键字限制不了强制类型转换。这里要说明的是强制类型转换必须跟一个表达式,因此,强制类型转换只能完成一个参数的转换。
#include <iostream>
using namespace std;
class Date
{
public:explicit Date(int year = 2023, int month = 10, int day = 16): _year(year), _month(month), _day(day){ }void Print() {cout << _year << "/" << _month << "/" << _day << endl;}
private:int _year;int _month;int _day;
};
int main()
{//强制类型转换Date d1 = (Date)5;Date d2 = (Date)(1, 2, 3);//Date d3 = (Date){1,2,3}表达错误,{1,2,3}不是一个表达式d1.Print();//输出5/10/16d2.Print();//输出3/10/16return 0;
}