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

bal*_*pha 2 c++ backwards-compatibility

我有一个现有的方法(或一般的功能),我需要增加其他功能,但我不想在代码中的其他地方使用该方法.例:

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

广泛用于代码库.现在我需要将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);
}
Run Code Online (Sandbox Code Playgroud)

或者我应该在头文件中声明一个默认参数,如

int bar(int x, int y=4);
Run Code Online (Sandbox Code Playgroud)

并只是扩展功能

int foo::bar(int x, int y)
{
 // ...
 return 2 * x + y;
}
Run Code Online (Sandbox Code Playgroud)

每种变体有哪些优缺点?

bee*_*f2k 7

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

原因是有两个级别的向后兼容性:

  1. 具有源级向后兼容性意味着您必须重新编译调用代码而不进行更改,因为新功能签名与旧功能签名兼容.这两个水平都可以实现; 默认值和包装/重载.

  2. 更强的级别是二进制级向后兼容性,甚至可以在不重新编译的情况下工作,例如,当您无法访问调用代码时.想象一下,你以二进制形式部署你的函数,就像在DLL等中一样.在这种情况下,签名具有完全相同的功能,使其无效 - 默认值不是这种情况 - 它们将破坏这种兼容性水平.

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