c语言有简单粗暴的强制类型转换,当然c++也有。问,可以将一个数字强制类型转换为一个类吗?
class TestCls
{
public:
int a;
};
int main(void)
{
TestCls t = 10;
return 0;
}
这样编译肯定编程报错:
加上强制类型转换?
TestCls t = (TestCls)10;
编译:
提示说找不到TestCls::TestCls(int),这显然是个构造函数。定义这么一个构造函数后:
class TestCls
{
public:
int a;
TestCls(int a)
{}
};
编译就通过了。
TestCls(int a)函数在这里是一个转换构造函数,转换构造函数的作用就是把传入的其他类型参数转换成类的对象。转换构造函数说白了还是一个构造函数,只不过该构造函数:
(1) 有且只有一个参数
(2) 参数是基本类型或者是其它类类型,也就是说不可以是本身的类型
在有转换构造的类TestCls中,我们可以不用加上强制类型转同样能通过编译,即:
TestCls t = 10;
那么执行这句代码时,编译器做了些什么?
10这个立即数默认int类型,它被用来初始化一个类对象,显然不符合逻辑,那么编译器会先查找类中是否有int类型参数的转换构造函数,即找到TestCls(int a),那么该行代码将会变成:
TestCls t = TestCls(10);
即编译器会去调用这个转换构造函数,生成一个临时对象进而初始化对象t,这是由于编译器具有的隐式类型转换功能,它会尽力尝试让程序编译通过。
但是在实际项目工程中,可能我们对于TestCls t =10;这样把数值直接初始化对象只是一个误操作,将10初始化对象t并非程序员本意,所以我把要去除这个编译器隐式转换的功能,这就需要explicit关键字修饰转换构造函数:
class TestCls
{
public:
int a;
explicit TestCls(int a)
{}
};
编译:
编译器不会进行隐式转换,倘若程序员还是想要实现将10初始化对象t,那就可以使用强制类型转换:
TestCls t = (TestCls)10;
或者
TestCls t = static_cast<TestCls>(10);