用转换操作符保护代码的安全,用转换操作符保护代码的安全
【 tulaoshi.com - C语言心得技巧 】
用转换操作符保护代码的安全
作者:Danny Kalev
编译:MTT 工作室
原文出处:Preserve Code Safety with Conversion Operators
(本文来源于图老师网站,更多请访问http://www.tulaoshi.com)string inf="mydata.txt";ifstream infile(inf.c_str());// 必须要转成 const char*同样,PSOIX 程序员需要将 <fstream 对象转换成文件描述符以便 使用本地系统调用。
class USD{private:__int64 dollars; //或者 long long, 依赖编译器 int cents;public:USD(__int64 d=0, int c=0) : dollars(d), cents(c) {} friend bool operator==(const USD& d1, const USD& d2); //...other overloaded operators and functions};唉,许多数学函数如:pow() 和 sqrt()都只认浮点变量。为了克服这个问题人们总是去重载关系操作符和算子。然而,你会发现这将带来大量无谓的编码,测试和维护工作。你想要的只不过是一个双接口:在适当的上下文中,USD 类对象除了应该提供安全的自动的到基本类型的转换外,它还应该提供上述所列的优点。
USD payment(203, 67);此时,你想将支付对象转换为浮点值 203.76。
class USD{public:operator double() //conversion operator{double temp=(dollars*100)+cents;return temp/100;}};让我们看看它是如何工作的。假设你想增加 5% 的支付:
double res=payment*1.05; //res=210.70这样能工作得很好,因为进行乘法之前转换操作符自动将支付转换为值 200.67。但是,在 USD 类的设计上有一个严重的缺点。请看下面的代码:
payment=payment*1.05; // 很糟现在,支付等于 210.00,这当然不是所期望的结果。让我们来看看为什么。右边子表达式 payment*1.05 首先被求值。正如你所看到的,这一部分没什么问题,产生的结果也是正确的。问题出在赋值上。编译器进行赋值的表达式如下:(本文来源于图老师网站,更多请访问http://www.tulaoshi.com)
payment=USD(__int64(200.67*1.05), 0);乘法表达式的结果被暗中转换为整型(因此丢失分数部分),然后被用作一个临时 USD 对象的参数。这就是为什么它会产生这样一个令人为难的结果。
class USD {public:explicit USD(__int64 d=0, int c=0): dollars(d), cents(c){}...这样,只有 USD 对象的赋值才被接受:
payment=USD(payment*1.05); // 没问题 payment=payment*1.05; // 编译出错添加另一个构造函数:
来源:http://www.tulaoshi.com/n/20160129/1486028.html
看过《用转换操作符保护代码的安全》的人还看了以下文章 更多>>