这篇文章主要介绍“C++为什么尽量不使用类型转换”,在日常操作中,相信很多人在C++为什么尽量不使用类型转换问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++为什么尽量不使用类型转换”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
按照C++核心准则的说法,应该尽量减少类型转换的使用,如果必须使用则使用narrow_cast和narrow。以下分几种情况讨论这个问题。
本来就不应该使用的情况:
观察如下代码:
class BaseClass{public: void bfun(){ cout << "BaseClass::bfun()" << endl; } virtual void vfun() { cout << "BaseClass::vfun()" << endl; }};class SubClass : public BaseClass{public: virtual void vfun() { cout << "SubClass::vfun()" << endl; }};
SubClass是BaseClass的派生类,可以说SubClass就是BaseClass,因此SubClass类型的指针向Base类型指针赋值的时候就不需要转换。
BaseClass* bc = new SubClass();bc->bfun();bc->vfun();
使用模板可以解决的情况:
观察下面的代码:
int mul(int a, int b) {
return a * b;
}
int main()
{
cout << mul(3, 5) << endl;
cout << mul(2.7, 5.6) << endl;
return 0;
}
代码中定义了一个整形数字的乘法函数,如果实参是整数的话函数可以正常执行;如果实参是浮点数,一方面编译会产生警告,另一方面计算会丢失精度(和警告的结果一致)。对实参进行类型转换虽然可以解决警告信息但是但是却无法解决丢失精度的问题。这时较好的的解决方式是使用模板:
template<typename T1, typename T2>auto mul(T1 a, T2 b) ->decltype(a*b){ return a * b;}
代码中使用了C++11新特性模板函数返回类型后置技术实现了更大的灵活性(两个实参可以是不同类型)。
int main(){ cout << mul(3, 5) << endl; cout << mul(2.7, 5.6) << endl; cout << mul(2.7, 5) << endl; return 0;}
无论哪种情况都不会出现编译警告,都可以得到正确的结果。
使用narrow_cast和narrow
如果设计者处于某种目的就是希望进行窄化类型转换时可以使用gsl提供的narrow_cast进行明确地表达这层意思。
cout << mul(narrow_cast<int>(3.4), narrow_cast<int>(2.8)) << endl;
如果希望进行类型转换,但是不希望发生窄化的情况下,可以使用narrow类型转换:
cout << mul(narrow<int>(3), narrow<int>(8)) << endl;cout << mul(narrow<int>(3.4), narrow<int>(2.8)) << endl;
第一种情况没有发生窄化,因此可以正常执行;第二种情况发生的浮点数到整数的窄化,会触发异常。
到此,关于“C++为什么尽量不使用类型转换”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。