使用类别方法重载 NSDecimalNumber 上的算术运算符

Overloading Arithmetic Operators on NSDecimalNumber using a Category Method

本文关键字:运算符 NSDecimalNumber 重载 方法      更新时间:2023-10-16

我正在做一个遗留项目,其中原始开发人员选择用浮点数表示货币价值(我知道......

我们已经承担了将项目中处理货币值的每个变量和属性切换到 NSDecimalNumber 的任务,如本问题的答案中所建议的那样。

我们遇到的一个小问题是 NSDecimalNumbers 不使用标准的算术运算符,而是使用方法。也就是说,当您使用算术运算符时,您添加的是内存地址,而不是实际值。在 Objective-C 中,重载算术运算符似乎是不可能的,尽管在 C++ 中是这样。

我认为可以在 NSDecimalNumber 上创建一个用 C++ 编写的类别方法。我知道可以将C++文件作为 Xcode iOS 项目的一部分添加和编译,尽管我没有这样做并且不熟悉C++。

在寻找如何完成这样的事情的例子时,我没有找到很多。谁能告诉我:

1)是否可以做我上面描述的?

2)语法是什么?

我相信你走在正确的轨道上,但可能面临更多问题。首先,正如@UKMonkey评论中已经提到的,您可能希望将其更改为过去float的一些typedef,然后根据需要更改该typedef

那么你的typedef没有理由指向一个NSDecimalNumber。您需要的是对应于某个接口,在您的情况下,该接口似乎是一些重载运算符。 话虽如此,您可能应该尝试创建一个新的 C++ 类,该类将包装NSDecimalNumber并具有自己的重载运算符。

这可以使用非常标准的C++程序来完成,但现在有趣的部分开始了......我不确定嵌入 ARC 支持的对象如何在C++结构中工作;你把它放进去的只是一个指针,你没有办法告诉它在分配时应该做什么。因此,您可能需要为此特定类禁用 ARC(可以按文件完成)并实现析构函数,这将释放您的十进制数。

我能想到的下一个问题是,如果你的类公开C++功能,这意味着所有使用/导入这个C++类的文件都需要支持C++这意味着它们必须重命名为.mm(或对它们使用C++标志)。

否则,我相信您几乎可以完成此操作,但我会向一些专家C++开发人员询问有关此类的意见,以了解如何最好地重载运算符以及如何正确处理分配。例如,如果您这样做MyValueType a = anotherMyValueTypeInstance;是否应该复制内部十进制数或重用为指针......此外,如果可以做任何事情来使用像MyValueType a = 0;这样的常量,否则您将需要使用函数(如果我没记错的话,C++甚至不支持静态方法),所以MyValueType a = MyValueTypeZero();.

至于在目标 C 中直接在NSDecimalNumber上添加运算符,即使在理论上也是不可能的。问题是你没有使用NSDecimalNumber而是NSDecimalNumber *这意味着你将在指针上重载运算符,而不是在对象本身上重载。编译器告诉您,根据设计,您无法对它们进行算术运算。就 C 而言,对 2 个指针求和是完全有效的,或者写成这样的东西:

MyType *buffer = (MyType *)1000; // Not that it makes sense
for(MyType *ptr = buffer; ptr < 1100; ptr++) doSomething(ptr[0]);