65.9K
CodeProject 正在变化。 阅读更多。
Home

DECIMAL包装类

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.35/5 (10投票s)

2003 年 5 月 19 日

CPOL

7分钟阅读

viewsIcon

61130

downloadIcon

1146

一个简单的 DECIMAL 包装类,适用于 C++ 代码与 VB 脚本/OLE 自动化代码等进行接口交互。

Sample Image - decimalwrap.png

引言

这是一个简单的实用工具类,它封装了 OLE 自动化类型 DECIMAL。其目的是让用户摆脱 ::VarDecXXX() 调用,并使 DECIMAL "表现得像 int 一样"。

互操作性

我的类 Decimal 公开继承自 DECIMAL。这样做的好处是,任何可以使用 DECIMAL 的地方,你也可以使用 Decimal。这使得该类与原始 COM 接口完全可互操作。

与 ATL 不同,我没有重载 *取地址* 运算符 (operator&),因此无需使用 CAdapt<> 来使该类适应 STL 容器。

接口

所有方法和构造函数都具有 throw() 属性,即,任何方法都不会抛出异常。但是,在调试构建中,可能会触发 assert。除以零就是其中之一。但是你已经知道不应该除以零了,对吧?

所有返回 Decimal& 值的方法都返回对 *this 的引用。因此,可以堆叠此类方法/操作。

构造函数

有十个构造函数。它们是:

  • Decimal()

    将对象初始化为值 0。

  • Decimal(const DECIMAL& decValue)

    使用参数 decValue 中包含的值初始化对象。

  • Decimal(char nValue)
  • Decimal(short nValue)
  • Decimal(long nValue)
  • Decimal(unsigned char nValue)
  • Decimal(unsigned short nValue)
  • Decimal(unsigned long nValue)

    使用参数 nValue 中包含的整数值初始化对象。

  • Decimal(float fValue)
  • Decimal(double fValue)

    使用参数 nValue 中包含的实数值初始化对象。

变异运算符

定义了以下运算符,它们的行为与 int 相同(因此我不会解释它们的用法和功能!)

  • Decimal& operator = (char nValue)
  • Decimal& operator = (short nValue)
  • Decimal& operator = (long nValue)
  • Decimal& operator = (unsigned char nValue)
  • Decimal& operator = (unsigned short nValue)
  • Decimal& operator = (unsigned long nValue)
  • Decimal& operator = (float fValue)
  • Decimal& operator = (double dValue)
  • Decimal& operator += (const DECIMAL& decRHS)
  • Decimal& operator -= (const DECIMAL& decRHS)
  • Decimal& operator *= (const DECIMAL& decRHS)
  • Decimal& operator /= (const DECIMAL& decRHS)
  • Decimal operator++(int)
  • Decimal operator--(int)
  • Decimal& operator++()
  • Decimal& operator--()

每个运算符的操作都如同它们是为 int 定义的一样。

变异方法

  • bool FromString(LPCOLESTR lpszNum, LCID lcid = 0)

    使用区域设置标识符 lcid 解析由 lpszNum 指向的字符串。解析后的值在返回之前会赋给 this 对象。

    如果此函数因字符串格式错误而失败,则返回值为 false

    如果区域设置标识符 lcid0,则将使用默认系统区域设置来解析字符串。

  • Decimal& MakeAbsolute()

    将此值设为绝对值。

  • Decimal& MakeNegative()

    将此值设为负值。

  • Decimal& MakeInteger()

    通过删除小数部分将此值设为整数。此函数的语义如下:*如果值为负数,则返回小于或等于此值的第一个负整数。*(语义描述复制并改编自 MSDN 文档。原始文本请参阅 VarDecInt 的手册页。)

  • Decimal& MakeFixed()

    通过删除小数部分将此值设为整数。此函数的语义如下:*如果值为负数,则返回大于或等于此值的第一个负整数。*(语义描述复制并改编自 MSDN 文档。原始文本请参阅 VarDecFix 的手册页。)

  • Decimal& MakeRound(int n)

    将此值四舍五入到第 n 位小数。

    请注意,n 必须大于或等于零。

非变异方法

以下函数是非变异的。它们与上面描述的变异方法相关,因此我在此处仅提及它们。例如,如果下面提及的方法名为 Absolute,则请参阅上面 MakeAbsolute 的文档。这些方法都具有不修改当前值的共同属性。相反,它们会创建一个临时值,该值被修改并返回。

  • Decimal Absolute() const
  • Decimal Negative() const
  • Decimal Integer() const
  • Decimal Fixed() const
  • Decimal Round() const

检查器

  • bool IsNegative() const

    如果此值为负数,则返回 true 的谓词。

  • bool IsZero() const

    如果此值为负数,则返回 true 的谓词。这是测试 Decimal 是否为零的最快方法。

  • BSTR ToString(LCID lcid = 0) const

    使用指定的区域设置将此值转换为 BSTR 字符串。如果区域设置标识符 lcid 为零,则将使用系统默认区域设置。

自由函数

以下自由函数,虽然逻辑上是 Decimal 的成员,但其工作方式如同为 int 设计的一样。

  • Decimal operator + (const DECIMAL& decRHS, const DECIMAL& decLHS)
  • Decimal operator - (const DECIMAL& decRHS, const DECIMAL& decLHS)
  • Decimal operator * (const DECIMAL& decRHS, const DECIMAL& decLHS)
  • Decimal operator / (const DECIMAL& decRHS, const DECIMAL& decLHS)
  • bool operator < (const DECIMAL& decRHS, const DECIMAL& decLHS)
  • bool operator > (const DECIMAL& decRHS, const DECIMAL& decLHS)
  • bool operator <= (const DECIMAL& decRHS, const DECIMAL& decLHS)
  • bool operator >= (const DECIMAL& decRHS, const DECIMAL& decLHS)
  • bool operator == (const DECIMAL& decRHS, const DECIMAL& decLHS)
  • bool operator != (const DECIMAL& decRHS, const DECIMAL& decLHS)

实现细节

我没有在我的代码中进行任何算术计算。我只是使用 OLE 自动化函数来操作 DECIMAL。我所做的只是将它们全部组合成一个薄薄的 C++ 包装类,这使得 DECIMAL 更愉快地使用。语法糖让软件更甜美。

如果你快速查看源文件,你会发现它是一个非常薄的包装器,据我所知,它增加的运行时间开销非常小。但是请,如果我错了,请纠正我。

买方注意

在使用此代码之前,您可能需要了解一些事项。

验证/断言

此代码目前使用 C 库版本的 assert(以及我自己的依赖于 assert 的宏 verify)。您可能希望在 ATL 或 MFC 环境中使用此代码之前更改它。一个简单的“查找和全部替换”应该可以解决问题。

变体

我没有包含任何处理 VARIANT 的方法。我想要一个简单而干净的接口。如果我需要与 VARIANT 的任何互操作性,我会添加该方法。在那之前,祝你好运——或者自己编写。

字符串

正如你可能已经注意到的,我只支持接口中的 BSTR 字符串。原因很简单;我打算在接近 VB[Script](以及可能其他奇怪的环境)的阴影区域中使用此代码,而 BSTR 是首选的字符串。我不相信臃肿的接口,所以除非我真的需要,否则我不会添加对任何其他类型字符串的支持。如果我需要,我会更新此源代码。如果你在我之前需要它,那么,你已经有了源代码!

VC6

我已将 VC6 作为此文章的关键字。但我承认我尚未针对该编译器进行测试。但由于我没有使用任何花哨的模板或其他新颖奇特的功能,我相信此代码在 VC6 中也能正常工作。事实上,我在另一个项目中有一个此类的旧版本,它在 VC6 中编译得很好。考虑到我删除了许多冗余代码,此类应该仍然可以编译。这是最高水平的质量保证。

四舍五入硬币

头文件中有一个名为 RoundToSmallestCoin 的自由函数。这是我在工作中编写的 POS 软件中使用的函数。我把它保留在此文件中是因为我懒惰。如果你觉得它使你的代码臃肿,只需选中它并按下删除按钮即可。

参考文献

Marc Clifton 写了一篇关于 decimal 类的类似文章。如果您的代码不打算与 COM/OLE 自动化环境一起使用,他的实现是完美的。您可以在此处找到他的文章。

免责声明和许可授予

免责声明

本文和源代码不提供任何形式的保证。对于数据损坏、硬件损坏或人身伤害,我概不负责。事实上,如果您使用此源代码,您不能要求我承担任何责任。

许可授予

但是,如果您觉得这段代码有用,并且我们有缘相遇,如果您请我喝啤酒(最好是我选择的啤酒),我不会说“不,谢谢”。但是,这不是必需的。如果可以接受,这是啤酒软件,否则就是免费软件。

© . All rights reserved.