扩展现有 API:使用默认参数还是包装函数?

发布于 2024-07-23 05:00:06 字数 602 浏览 7 评论 0原文

我有一个现有的方法(或一般的函数),我需要增加额外的功能,但我不想破坏代码中其他地方对该方法的任何使用。 示例:

int foo::bar(int x)
{
 // a whole lot of code here
 return 2 * x + 4;
}

在代码库中广泛使用。 现在我需要将 4 设为参数,但任何已经调用 foo::bar 的代码仍应收到它所期望的内容。 我应该扩展并重命名旧方法并将其包装到新方法中,

int foo::extended_bar(int x, int y)
{
 // ...
 return 2 * x + y;
}

int foo::bar(int x)
{
 return extended_bar(x,4);
}

还是应该在头文件中声明一个默认参数

int bar(int x, int y=4);

,然后扩展函数

int foo::bar(int x, int y)
{
 // ...
 return 2 * x + y;
}

每个变体的优点和缺点是什么?

I have an existing method (or function in general) which I need to grow additional functionality, but I don't want to break any use of the method elsewhere in the code. Example:

int foo::bar(int x)
{
 // a whole lot of code here
 return 2 * x + 4;
}

is widely used in the codebase. Now I need to make the 4 into a parameter, but any code that already calls foo::bar should still receive what it expects. Should I extend and rename the old method and wrap it into a new one like

int foo::extended_bar(int x, int y)
{
 // ...
 return 2 * x + y;
}

int foo::bar(int x)
{
 return extended_bar(x,4);
}

or should I declare a default argument in the header file like

int bar(int x, int y=4);

and just extend the function

int foo::bar(int x, int y)
{
 // ...
 return 2 * x + y;
}

What are advantages and disadvantages of each variant?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

萧瑟寒风 2024-07-30 05:00:06

我通常使用包装函数(大多数时候通过重载)而不是默认参数。

原因是存在两个级别的向后兼容性

  1. 具有源代码级向后兼容性意味着您必须在不进行任何更改的情况下重新编译调用代码,因为新的函数签名与旧的兼容。 两者都可以达到这个水平; 默认值和包装器/重载。

  2. 更强的级别是二进制级向后兼容性,甚至无需重新编译即可工作,例如,当您无权访问调用代码时。 想象一下,您以二进制形式部署函数,例如在 DLL 中等。在这种情况下,签名必须完全相同才能使其正常工作,而默认值则不然 - 它们会破坏这种兼容性级别.

包装函数的另一个优点是 - 如果您的应用程序具有任何类型的日志记录 - 您可以在旧函数中转储警告,该函数将在未来版本中过时,并且建议使用新函数。

I usually use a wrapper function (via overloading most of the time) instead of default parameters.

The reason is that there are two levels of backward compatibility:

  1. Having source-level backward compatibility means that you have to recompile the calling code without changes, because the new function signatures are compatible to the old ones. This level can be achieved with both; default values and wrappers/overloading.

  2. A stronger level is binary-level backward compatibility, which even works without recompilation, e.g. when you don't have access to the calling code. Imagine you deploy your function in binary form, like in a DLL, etc. In such a case, the signatures have the be exactly the same to make it work, which is not the case for default values - they will break this level of compatibility.

Another advantage of wrapper functions is - if your application has logging of any kind - you can dump out a warning in the old function that it will become obsolete in future versions and that it is recommended to use the new one.

后来的我们 2024-07-30 05:00:06

使用 C++ 的时间越长,我就越不喜欢默认函数参数。 我无法指出我不喜欢的任何具体原因,但我发现如果我使用它们,我几乎总是会在以后删除它们。 因此,我的(主观)投票支持新的命名函数 - 该名称当然可以与旧函数的名称相同。

The longer I use C++, the less I like default function parameters. I can't pinpoint any specific reason for my dislike, but I find that if I use them, I almost always end up removing them later. So my (subjective) vote goes for the new named function - the name could of course be same as that of the old one.

朦胧时间 2024-07-30 05:00:06

我个人认为,隐性行为是万恶之源(之一)。

任何对维护者或调用者混淆被调用目标身份的内容都应该有非常充分的理由,特别是如果它是主要 API 的一部分。

因此,我强烈反对使用默认操作的选项。

此外,我相信,如果可以使用不同数量的参数调用某个函数,那么该函数的两个版本都有本质上的不同,或者它们做得太多了。 区别可能应该在名称中,并且应该比“_extended”更有意义

I personally believe that implicit behaviors are (one of) the roots of all evil.

Anything that obfuscates for a maintainer or caller the identity of the target being invoked should have a very strong justification, especially if it is part of a major API.

Therefore, I would argue strongly against the option with the default operation.

In addition, I believe that if a certain function can be invoked with a different number of parameters, then there is something inherently different both versions of the function or they are doing too much. The distinction should probably be in the name, and should probably be more meaningful than "_extended"

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文