有没有可用的 C + + 重构工具?

有没有人知道一个功能齐全的 C + + 重构工具,可以可靠地处理大型代码库(大约100.000行) ?

在过去几年中,我反复尝试了所能找到的任何东西: SlickEdit、 Eclipse CDT。它们一点用都没有。

总结 : 我花了一些时间来评估“ Visual Assist X”和“ Refactor for C + +”。两者都有一些令人印象深刻的特点,但两者都远非完美。如果不进行手动修改,提取大量代码通常是不能令人满意的,因此也没有回报。

“视觉辅助 X”有很好的功能,如更完整的自动完成等。但是它会导致如此多的闪烁,并且在某些点上会减慢很多。

因此,我认为答案是: “不,没有用于 C + + 的生产就绪的重构工具”

更新日期: 2015年3月 至于 hdoghmens 今天的回复,我尝试了 Resharper for C + + 。 他的链接 Https://www.jetbrains.com/resharper/ 没有提到任何关于 C + + 的内容。但我发现 Resharper C + + 是一年多前在这里发布的:

Https://www.jetbrains.com/resharper/features/cpp.html

我尝试使用 VC2010使用20MB 的代码基。

测试1: 提取方法: 导致 Resharper 异常。没有更改源代码。

测试2: 不同来源的提取方法: 没问题

测试3: 更改提取函数的签名: 导致 C + + 代码中断:

bool myclass::do_work123(<unknown long Color>int& Filled*&, long, int&)

也许这就是为什么 C + + 在主页上没有列出来的原因。

在我看来,这个问题的答案仍然是 “不”

56840 次浏览

Visual Assist 和 Visual Studio 使得处理大型代码库变得更加容易。视觉辅助在跟踪类或成员的使用方式方面做得很好,而且比搜索和替换更有效地在没有误报的情况下对其进行重命名。

我发现使用 Visual Studio 的 视觉辅助 X非常有用。另一个选择是 为 C + + 重构

如果使用 Visual C + + (Express Edition 是免费的) ,可以使用 Www.wholetomato.com 的视觉辅助(链接到 C + + 重构特性)。

它有一个30天的试用期,我们发现它比 Visual C + + 产品本身的内置智能感知更快,功能更全。

Mozilla 有自己的重构工具 Pork (维基百科开发者维基)。给你是 Pork 背后开发人员的博客。据我所知,Pork 在 Mozilla 的重构中得到了成功的应用。

如果您来自 * nix 土地,那么猪肉应该会有所帮助,对于 VisualStudio,我也推荐 VisualAssist。

目前我不推荐用于 C + + 的 任何重构工具,当然也不推荐用于10万行以上的大型代码库。我一直希望这会有所改变,就像《观察家报》那样,我希望有一天会有所改变。我担心,在我们看到任何真正好的工具之前,语言本身可能必须进行重大改变。

顺便问一下,SlickEdit 是否放弃了它的重构特性?

如果你想重新设计你的代码库: MOOSE。但是,这是一个大量的分析和再造工具的集合,而不是一个编辑器。

如果您正在使用 emacs,请尝试 X 工厂。它支持方法提取、类/函数/变量的重命名和插入/删除/移动参数。

我认为 DMS 软件工程工具包是这样的。它是一个代码转换引擎,专为大规模处理 C + + 而设计。虽然不知道输出是多么优雅。

我们的 软件再造工具包是一个转换引擎,设计用于在大量代码(包括 C + +)上执行复杂的转换。它已经被用于对数百万行代码的系统进行可靠的更改。它通过使用编译器精确的语言分析器和转换器进行操作。

它有一个具有名称和类型解析的完整 C + + 解析器,构建代码的 AST,可以应用过程或源到源的转换(使用 C + + 表面语法)来修改这些树,并用保留的注释重新生成可编译输出。(编辑: 7/1/2011: 现在 C + + 1X 已经达到了我们理解标准的程度:)

它已经被用于大规模的再工程项目,包括 C + + 组件重新架构,以及100% 全自动的语言间翻译。 你可以在网站上看到。

DMS 还用于构建任意源分析工具。例子包括克隆检测、测试覆盖率、智能差异(比较源代码结构和抽象编辑操作,而不是简单的插入和删除代码行)等。

它(目前)不是一个交互式重构工具。我们相信,要做好大多数重构,您需要进行深入的控制和数据流分析。DMS 有通用的机制来支持这一点,目前该机制是为 C、 COBOL 和 Java 实现的,下一个目标是 C + + 。这是个艰难的工作。在这类问题得到很好的解决之前,你不会看到任何人提供大量严肃的 C + + 重构工具。 首先,您需要一个完整的 C + + 解析器:-}

2011年7月5日编辑: 看来我们要试试互动版了。我们已经赢得了能源部第一阶段 SBIR 来研究如何做到这一点。参见 http://science.energy.gov/sbir/awards-and-general-stats/fy-2011/phase-i-by-state/?p=1#tx(寻找“ Texas”下的语义设计)。 不要急于期待结果,这只是三阶段多年计划的开始,以获得一个工具。

2011年8月11日编辑: 第一个进展... 我们现在处理所有的 C + + 0x 和 OpenMP 指令。

编辑1/4/2012: 对 C + + 代码进行完整的控制流分析。

2014年9月15日编辑: 现在已经掌握了 C + + 14前端解析器/转换引擎。在这一点上,甚至可以相当可靠地重命名:-}

人们肯定会提到,发条是一个商业代码重构套房。它看起来非常有希望,当你通过演示视频。

我预计在未来几年内,将极大地改变 C + + 重构工具的面貌。它是一个开源的、模块化的编译器,它公开了一个用于解析和语义分析 C + + 代码的 API。IDE 和其他工具将能够使用这个 API,而不是完成编写自己的解析器和语义分析器的艰巨工作。

Google 已经使用 clang 开发了一个大规模的重构工具。

Microsoft 现在为 Visual Studio 2013提供了一个 C + + 重构扩展: Http://visualstudiogallery.msdn.microsoft.com/164904b2-3b47-417f-9b6b-fdd35757d194

毫无疑问,Resharper Ultimate是我们的出路。幸福保证:)

截至2015年3月的 Beta 版本。

我找到了下面这个 Visual Studio 2013插件: Visual C + + Refactoring by Microsoft.

这只是一个简单的重命名工具,但它的工作完美无缺。它在右键单击一个符号后添加以下上下文菜单:

enter image description here

如果您使用 emacs,而且还没有尝试过,我建议您尝试 标签(还有一个针对 vim 的 包裹)。它是一个基于 clang 的客户机/服务器应用程序,可以对 C/C + + 代码进行索引,其特性包括:

  • 进入定义/声明
  • 查找所有参考资料,转到下一页/上一页
  • 重命名符号
  • 与叮当的“固定部件”相结合

在看了这个为我引入了 rtag (和 emacs)的 谈谈之后,我决定尝试一下。

(我不得不说,我只是在我的 QtCreator 未能正确地重命名一些符号之后才走到这一步,这对我现在使用这个伟大的 IDE 来说是一个阻碍)

除了 rtag 所支持的功能之外,我还需要一些其他的简洁的特性,包括:

  • 创建函数定义/原型
  • 提取函数提取函数
  • 创建 getter/setter 方法

对于这些,我建议对 emacs 使用 语义重构包(不确定是否有 vim 的替代品)

一般来说,基于 clang 的工具看起来很有前途。如果您对用于 C + + 重构的 clang 工具的更多信息感兴趣,包括用于具有大型代码库的项目的信息,钱德勒 · 卡鲁斯(Chandler Carruth)提供了 一些 很好演讲。

我建议你试试 Lattix。它允许您分析大型 C/C + + 代码库以发现体系结构,识别有问题的依赖项,并重新设计代码以提高模块性并减少技术债务。Lattix 还提供了许多算法来帮助重构过程。这些算法可以帮助您了解如何将元素从层次结构的一个部分移动到另一个部分,以打破循环并移动子系统,从而提高子系统的耦合性和内聚性。下面是 Lattix 分析 Android 内核(160万个 C/C + + LOC)的结果。 老实说,我为 Lattix 工作

很抱歉这么晚才找到这个问题。我的学生和助手从2006年就开始从事 C + + 重构的工作。大多数 CDT 重构基础设施是由我在 IFS 软件研究所的团队构建的。几年来,我们一直在提供支持 C + + 代码现代化重构的 CDT 版本。如果工作空间设置正确,则可以使用大型代码库。https://cevelop.com免费提供

问题在于 C + + 模板。截至2019年,我还没有发现任何支持 C + + 模板的重构工具。我试过 VS2019,VisualAssist,Clion,QtCreator。

举个例子:

#include <iostream>


struct foo { void print() {} };
struct bar { void print() {} };


template <typename T>
void call_print(T&& v) { v.print(); }


void print() {}


int main()
{
call_print(foo{});
call_print(bar{});
return 0;
}

如果我在 foo::print上运行重命名重构,bar::print也应该自动重命名。因为它们是通过 call_print函数模板实例化链接的。