11

在像 OpenCV 这样完善的 C++ 库中添加或修改单个类方法的最佳实践是什么,同时仍然重用剩余的库代码,最好是 lib 格式。

在这一点上,我知道的唯一方法是将属于特定库(比如说 OpenCV 的核心库)的所有源文件和头文件复制到当前源文件夹,修改一个函数并使用其余代码重新编译模块. 理想情况下,我希望能够以它们的方式链接所有当前的 .lib 文件,但只需为在这些库中定义的类定义一个新方法(或修改当前方法),以一种我的方法实现取代的方式默认库文件的实现。

继承似乎并不总是一种选择,因为有时基类具有正确继承类实现所需的私有成员。

4

3 回答 3

9

我不知道 C++ 中有一种干净的方式来完成您的要求。您真正要求做的事情(假设您需要使用或修改私有方法)违反封装,而 C++ 语言旨在不允许您这样做。

存在几个选项:

  • 文件.lib只是文件的集合.obj.obj你的编译器工具链应该有一个命令行程序.lib来添加、删除和.obj替换.lib. 我怀疑这个解决方案会是丑陋和脆弱的。
  • 如果有一些库不做而应该做的事情,那么您总是有机会向库作者提交补丁或功能请求以进行更改。当然,这可能需要一段时间,如果它完全有效的话。
  • 正如@fatih_k建议的那样,将您的更改添加为朋友类是可行的。如果您对 OpenCV 所做的唯一friend更改是在头文件中添加一行,那么库的ABI将保持不变,您不必触摸.lib.
  • 最干净的选择是简单地接受您需要修改 OpenCV 库并跟踪其源代码以及您的修改以及您自己开发的源代码,并与您自己构建的源代码一起构建它。这是一种非常常见的方法,并且存在各种模式和技术可以帮助您做到这一点;例如,Subversion 有供应商分支的概念。这种方法需要更多的设置工作,但从长远来看绝对是最干净的。
于 2013-03-26T15:27:58.543 回答
4

如果这个库已经编译好了,那么你就没有什么可移植的和干净的了。

如果您知道程序将在其上运行的特定目标体系结构,您可以获取指向成员函数的指针,并使用jmp您自己的方法版本的指令对指令进行修补。如果方法是虚拟的,则可以修改 vtable。这些需要大量特定于编译器的知识,并且不可移植。

如果库在动态链接存档中提供,您可以提取存档并将方法替换为您自己的版本,然后重新打包存档。

另一种方法是您可以从标题中复制类的声明并添加朋友声明。或者,您可以在包含头文件之前#define private public或之前执行此操作。#define private protected这些将使您可以访问他们的私人成员。

对于上述任何一项,您需要注意您的更改不会修改库的 ABI。

于 2013-03-26T15:28:47.423 回答
1

好吧,OpenCV 在 BSD 下获得许可,因此您可以进行更改而不必担心重新发布它们。

您始终可以遵循代理设计模式并将新方法添加到库外部,然后从那里调用库。这意味着您无需担心维护自己的 OpenCV 版本并分发它。在 Wiki 上有更多关于代理模式的信息,可以帮助您入门。

于 2013-03-26T15:21:31.483 回答