c++如同C语言一样, 有语言本身的隐式类型转换。如将char转换成int int转换为double等 c++还可以将double转换成int 即向下转换。
这是语言本身提供的,我们不能控制。但是对于我们自己写的类却可以自己控制。有两种函数提供这种类型的转换:隐式类型转换操作符与单一变量构造函数。
尽量不要提供这两种函数
原因:
1.对于隐式类型转换操作符:
它可能在你不知道的时候就调用了,得到与你预期不一样的结果。
如下面一个类:
class Rational
{
public:
...
operator double() const;
};
函数会在以下情况被调用
Rational r(1,2);
double d=0.5*r;
但是,若你想要输出1/2.你可能会这样写:
Rational r(1,2);
cout<<r;
假设你没有定义operator<< ,依然可以编译通过,编译器会找到operator double函数来完成输出,显然结果将是double,并不是你想要的结果。
解决方法:以另一个功能相同的函数来代替隐式类型转换操作符。
如:利用一个函数asDouble来封装operator double
结果如下:
cout<<r;//错误
cout<<r.asDouble;//正确
2.单自变量的构造函数,即只有一个参数的构造函数或者只有一个需要传参的参数,其他参数都有默认值的构造函数。
如下面的例子:
template<class T>
class array
{
array(int size);
array(int lowbound,int hbound);
...
};
第一个构造函数可以作为一个类型转换函数。
例考虑一个用来对array<int>做比较的函数
bool operator==(const array<int>& l,const array<int>& h);
array a(10);
qrrqy b(10);
..
for(int i=0;i<10;i++)
{
if(a==b[i])//这里不小心写成了a
...
};
编译器对上述代码并不报错,编译器会将b[i]隐式转换成static_cast<array<int> >b[i];
变成了a与一个临时对象进行比较。
显然,这并不是你所需要的。
解决办法:
1.在构造函数那里加上explicit关键字,可以使得构造函数不能隐式转换。
2.将size写成一个类,因为规定:没有任何一个转换程序可以内含一个以上的“用户指定转换行为”。
总结:对“定制的类型转换函数”要提高警惕。
上述例子摘录自more effective c++