通过构造函数来转换
如果有这样的构造函数:
Node(int _x);
则可以有这样的语句:
Node a=2;
这条语句实际上将使用2作为构造函数的参数创建临时变量,然后将该变量复制到a中,由于这一步是自动进行的,所以称为隐式转换。注意只有一个参数的构造函数(或者有多个参数,但除了第一个,其他的参数都有默认值)才能用来转换。
可以用于隐式转换的情况(前提是有满足条件的构造函数):
(1)将Node对象初始化成int时。
(2)将int赋给Node对象时。
(3)将int值传递给接受Node参数的函数时。
(4)函数返回值类型为Node但实际返回了int时。
(5)在上述任一情况下,使用可转换为int类型的内置类型时。
Node a = 2.6;
上面这条语句会首先将double转换为int,再调用构造函数,最终a的值是2。如果此时还有另一个构造函数如下:
Node(long _x);
编译器会拒绝Node a=2.6这种语句,因为double可以转换成int和long,产生二义性。
但其实有更好的转换方法而不是用构造函数,因此C++提供了关键字explicit来关闭这种自动特性。这样声明构造函数,将不允许隐式转换。
explicit Node(int _x);
但可以强制类型转换:
Node a = (Node)2.6;
转换函数
如果要将某种类型转换成类类型,可以使用转换函数。转换函数是自己定义的强制类型转换。
转换函数的语法:operator typeName()。
转换函数的约定:
(1)必须是类方法。(2)不能指定返回类型。(3)无参数。
Sample:
#include<iostream>
#include<cstdio>
using namespace std;
class Node
{
private:
double x;
public:
Node(double _x)
{
x = _x;
}
operator int() const
{
return int(x + 0.5); //自定义的int强制转换函数,四舍五入
}
operator double() const
{
return x;
}
};
int main()
{
Node t(1.5);
cout << (int)t << " " << (double)t << endl;
return 0;
}
虽然无返回类型,但也是需要返回值,实际上函数名typeName就是要返回的类型。定义了转换函数之后,就可以在特定的地方执行强制转换。当然也可以隐式转换,仅当没有产生二义性时才能通过编译。如以下将会产生编译错误:
long x = t;
因为int和double都可以转换成long,产生二义性。在C++11中用explicit关键字声明表示只允许强制转换。