c++ - 将 C 源代码转换为 C++

标签 c++ c refactoring legacy program-transformation

您将如何将相当大 (>300K)、相当成熟的 C 代码库转换为 C++?

我想到的那种 C 被分成大致对应于模块的文件(即比典型的基于 OO 类的分解更细化),使用内部链接代替私有(private)函数和数据,以及公共(public)函数和数据的外部链接.全局变量广泛用于模块之间的通信。有一个非常广泛的集成测试套件可用,但没有单元(即模块)级别的测试。

我想到了一个总体策略:

  1. 编译 C++ 的 C 子集中的所有内容并使其正常工作。
  2. 将模块转换为大型类,以便所有交叉引用都由类名限定范围,但将所有函数和数据保留为静态成员,并使其正常工作。
  3. 使用适当的构造函数和初始化的交叉引用将大类转换为实例;酌情用间接访问替换静态成员访问;并让它发挥作用。
  4. 现在,将项目视为一个不良因素的 OO 应用程序,并在依赖项易于处理的情况下编写单元测试,并在不易于处理的情况下分解为单独的类;这里的目标是在每次转换时从一个工作程序转移到另一个工作程序。

显然,这将是相当多的工作。有没有关于这种翻译的案例研究/ war 故事?替代策略?其他有用的建议?

注意 1:该程序是一个编译器,可能数以百万计的其他程序依赖于它的行为不变,因此大规模重写几乎不是一种选择。

注 2:源代码已有近 20 年的历史,每年可能有 30% 的代码流失(修改的行数 + 添加的行数/之前的总行数)。换句话说,它被大量维护和扩展。因此,目标之一是提高可维护性。

[为了这个问题,假设翻译成 C++ 是强制性的,而将其留在 C 中是 不是 一种选择。添加此条件的目的是清除“将其保留在 C 中”的答案。]

最佳答案

几个月前刚刚开始做几乎相同的事情(在一个有十年历史的商业项目中,最初是用“C++ 只不过是带有智能 structs 的 C”理念编写的),我建议使用与吃大象相同的策略:一次咬一口。 :-)

尽可能将其拆分为可以在对其他部分影响最小的情况下完成的阶段。构建立面系统,如 Federico Ramponi建议,是一个好的开始——一旦所有东西都具有 C++ 外观并通过它进行通信,您就可以相当肯定地更改模块的内部结构,确保它们不会影响外部的任何东西。

我们已经有了一个部分 C++ 接口(interface)系统(由于之前的重构工作较小),所以这种方法在我们的案例中并不困难。一旦我们将所有东西都作为 C++ 对象进行通信(这花了几周时间,在一个完全独立的源代码分支上工作,并在获得批准后将所有更改集成到主分支),我们很少能编译出一个完全我们出发前的工作版本。

转换尚未完成 - 我们为临时版本暂停了两次(我们的目标是每隔几周发布一次单点版本),但进展顺利,没有客户提示任何问题.我们的 QA 人员也只发现了一个我记得的问题。 :-)

关于c++ - 将 C 源代码转换为 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/199627/

相关文章:

python - 错误 : ambiguous overload for 'operator/'

javascript - 将 JavaScript 移动到外部文件,当它包含 document.getElementById ('<%= control.ClientID%>' 时)

c# - 如何用很多参数重构类的方法?

c++ - C++ 中的编译时断言?

c++ - openCV 中的彩色对象跟踪不断检测皮肤

c++ - 仅优化调试配置中的单个方法

c++ - 运行现有应用程序以更改数据库,好主意吗?

c++ - 尝试在 std::map 中插入抽象类时没有匹配的调用函数

C 数组的数组 : why do I need to cast TO const here?

c - 为什么代码打印的字符数与获取的字符数一样多