您的位置:首页 > 其它

条款五:对自定义的类型转换保持警觉

2016-08-09 10:47 162 查看

条款五:对自定义的类型转换保持警觉

  C++的强大之一是它不同于C语言严格的数据类型检查,但是有些情况下C++编译器为了方便用户操作给用户带来的一些麻烦也不容忽视。

1. 隐式数据类型转换

  这里说到的隐式类型转换和普通的隐式数据类型转换相同,但是直接操作符却不是来自系统而是用户,比如有一个类:

class fun
{
int deno;
int mole;
public:
fun(int d, int m) :mole(m), deno(d){}
operator double()const
{
return deno / static_cast<double>(mole);
}
};


  如果我们执行代码打印一个fun类型的对象不会报错而是直接输出一个double,因为发生了隐式类型转换,这可能在这里影响不大,但是有些时候的确会造成错误。解决方法也很简单,自定义一个<<重载操作符即可。或者自定义一个成员函数来实现operator double()的功能。

2. 构造函数导致的隐式类型转换

  在C++中隐式数据类型转换不仅仅来自于来源于C语言的数据类型转换,而且带有参数的构造函数也会触发隐式类型转换。比如有一个类

template<class T>
class Array
{
public:
Array(int size)
{
}
T& operator[](int index)
{
return 0;
}
};
//这个类只是简写,理解意思就行
bool operator==(Array<int> _rst, Array<int> _snd)
{
}


  在对类Array执行if (_array_rst[2] == _array_snd[2])因为大意写成if (_array_rst == _array_snd[2]),这样编译器不会报错还会进行比较,因为_array_snd[2]是一个int数,而Array的拷贝构造函数需要一个int类型这就触发了隐式类型转换。这可能在工程中导致一些不可预见的错误。

  
  解决的办法是使用explicit关键字对构造函数进行限制,这样编译器就不会触发因拷贝构造函数引起的饮食类型转换。

解决办法

  1. 添加explicit关键字,禁止拷贝构造函数的隐式类型转换

  2. 使用嵌套类。如将以上类修改为

template<class T>
class Array
{
public:
class ArraySize
{
private:
int _size;
public:
int size()
{
return _size;
}
ArraySize(int num) :_size(num){}
};
Array(ArraySize size)
{
}
T& operator[](int index)
{
return 0;
}
};


  这就是一个代理类(proxy)可以解决隐式类型转换问题

总结

  对于用户自定义类型转换,避免用它;而拷贝函数导致的隐式类型转换要考虑所做的具体项目的环境不能说那一种方法最好,深思熟虑。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  隐式类型转换