当返回类型需要更改时,有哪些策略可以弃用函数?例如,我有:
BadObject foo(int); // Old function: BadObject is being removed.
Object foo(int); // New function.
Object
和BadObject
在内部非常不同,并且交换其返回类型会破坏我的库的当前用户的代码。我的目标是避免这种情况。
我可以标记BadObject foo(int)
deprecated,并为用户提供更改受影响代码的时间
但是,我can't overload foo
based on return-type。 foo
命名非常好,不需要额外的参数。如何在保持旧版本的同时将新功能添加到我的库中,至少有一段时间?
在不破坏过多依赖代码的情况下弃用旧功能的策略是什么,同时为用户提供迁移到新版本的时间?理想情况下,我会保留当前的函数名称和参数列表,因为它现在命名得很好。感觉这个应该是一个相当普遍的问题:什么是解决它的好方法?
答案 0 :(得分:4)
虽然解决方案 会强制您更改功能名称,但这将是旧用户和新用户之间的妥协。
所以 - 将旧的foo
重命名为deprecatedFoo
,将新的foo
重命名为foo2
(或您想要的任何内容)。然后,在您的库中包含的头文件中,您可以简单地:
#define deprecatedFoo foo
并且在函数内部执行:
#warning ("This function is deprecated. Use 'foo2' or change the #define in LINE in file HEADER.")
旧版本的用户无需更改其代码,系统会发出警告,新用户可能会收听并更改#define
以使用新版foo
在下一个版本中,您只需删除旧的foo
和define
。
答案 1 :(得分:0)
我认为一个典型的例子是Boost's Spirit。
来自FAQ:
在介绍Spirit V2时,我们重新构建了目录结构 为了同时容纳两个版本。所有的 Spirit.Classic现在位于目录
中升压/精神/家庭/经典
其中上面的目录包含转发标头到新的 位置允许保持应用程序兼容性。该 转发标头发出警告(从Boost V1.38开始)告诉 用户更改其包含路径。请期待以上 目录/转发标题即将消失。
这解释了对目录
的需求升压/精神/包括
也包含转发标头。但这次是标题 不会消失。我们鼓励应用程序编写者只使用 包含在此目录中的包含。这使我们能够进行重组 如果需要,下面的目录无需担心应用程序 兼容性。请仅在您的应用程序中使用这些文件。如果它 事实证明,某些转发文件丢失,请将此报告为 一个错误。
您可以通过将新旧版本保存在单独的目录中并使用转发标头来保持兼容性来简化迁移。用户最终将被迫使用新标题。
SDL 2.0有不同的方法。它们不提供兼容性层,而是提供迁移指南,引导用户完成最显着的更改。在这种情况下,您可以帮助用户了解他们需要重新构建代码的方式。
答案 2 :(得分:0)
如果要使Object
类继承自BadObject
(您将暂时保留),该怎么办?那么旧的用户代码将不会知道这一点,所以如果您的新“foo”函数仍然正确地返回您的对象,它将不会中断。