Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否有一个工具可以添加;凌驾;现有C++;代码 任务 我试图找出如何在C++中的一个大的主体中已经覆盖的所有现有方法中添加C++ 0x的标识符,而不是手工操作。_C++_Overriding_C++11 - Fatal编程技术网

是否有一个工具可以添加;凌驾;现有C++;代码 任务 我试图找出如何在C++中的一个大的主体中已经覆盖的所有现有方法中添加C++ 0x的标识符,而不是手工操作。

是否有一个工具可以添加;凌驾;现有C++;代码 任务 我试图找出如何在C++中的一个大的主体中已经覆盖的所有现有方法中添加C++ 0x的标识符,而不是手工操作。,c++,overriding,c++11,C++,Overriding,C++11,(我们有许许多多、几十万行代码,手工操作完全是不可能的。) 当前想法 我们的编码标准说,我们应该针对派生类中的所有隐式虚方法添加virtual关键字,尽管这是完全不必要的(以帮助理解) 因此,如果我自己编写添加的脚本,我会编写一个脚本,读取所有标题,找到以virtual开头的所有函数,并在下面的分号之前插入override。然后在支持重写的编译器上编译它,并修复基类中的所有错误 但我真的不想用这种土生土长的方式,因为: 很明显,这将是一个乏味且容易出错的过程 不是每个人都记得每次添加virtu

(我们有许许多多、几十万行代码,手工操作完全是不可能的。)

当前想法 我们的编码标准说,我们应该针对派生类中的所有隐式虚方法添加
virtual
关键字,尽管这是完全不必要的(以帮助理解)

因此,如果我自己编写添加的脚本,我会编写一个脚本,读取所有标题,找到以virtual开头的所有函数,并在下面的分号之前插入
override
。然后在支持重写的编译器上编译它,并修复基类中的所有错误

但我真的不想用这种土生土长的方式,因为:

  • 很明显,这将是一个乏味且容易出错的过程
  • 不是每个人都记得每次添加virtual关键字,因此此方法将错过一些现有的覆盖
是否有现有的工具?

这样,是否已经有一个工具来解析C++代码,检测现有的重写方法,并将<代码>覆盖> <代码>附加到它们的声明?

(我知道一些静态分析工具,比如警告那些看起来应该被重写的函数。我所追求的是那些实际上会破坏我们代码的东西,这样将来重写中的错误将在编译器时被检测到,而不是稍后在静态分析中被检测到)

(如果有人想指出C++03不支持“覆盖”…实际上,我会添加一个宏,而不是实际的“覆盖”标识符,以便在不支持此功能的旧编译器上使用我们的代码。因此,添加标识符后,我将运行单独的脚本,用我们将要使用的任何宏替换它…)

提前感谢…

我们的C++11功能可以做到这一点

DMS是一个针对任意编程语言的通用程序转换系统;C++前端允许它处理C++。DMS解析、构建精确的AST和符号表(这对于C++来说很难做到),支持查询AST节点和树的属性,允许在树上进行过程转换和源到源转换。进行所有更改后,可以重新生成修改后的树,并保留注释

您的问题需要找到派生的虚拟方法并对其进行更改。要执行的DMS源到源转换规则如下所示:

    source domain Cpp.  -- tells DMS the following rules are for C++

    rule insert_virtual_keyword (n:identifier, a: arguments, s: statements):
       method_declaration -> method_declaration " =
       " void \n(\a) { \s } "  ->  " virtual void \n(\a) { \s }"
       if is_implicitly_virtual(n).
这些规则与语法树相匹配,因此它们不能与注释、字符串或其他内容不匹配。有趣的引号不是C++字符串引号;它们是元引号,允许规则语言知道它们内部的内容必须被视为目标语言(“Cpp”)语法。反斜杠是从目标语言文本中转义出来的,允许与任意结构进行匹配,例如,\a表示需要“a”,它被定义为语法类别“arguments”

您需要更多的规则来处理函数返回非void结果等情况,但不需要太多规则

有趣的部分是实现控制转换应用程序的谓词(返回TRUE或FALSE):is_隐式地_虚拟。该谓词采用(抽象语法树)方法名n。 这个谓词将参考完整的C++符号表来确定N是什么。我们已经从它的语法设置知道它是一个方法,但我们想知道它在什么样的类上下文中。 符号表提供了方法和类之间的链接,类的符号表信息告诉我们类继承自什么,对于这些类,它们包含哪些方法以及它们是如何声明的,最终导致发现(或不发现)父类方法是虚拟的。要做到这一点,代码必须实现为与C++符号表API相对应的过程代码。然而,所有的艰苦工作都完成了;符号表是正确的,并且包含对所需的所有其他数据的引用。(如果您没有这些信息,就不可能从算法上做出决定,任何代码更改都可能是错误的)

过去,DMS已经被用来对程序代码进行大规模的C++代码修改。(在网站上查看C++的C++主题重构页面)。

(我不是C++专家,只是DMS架构师,所以如果我有一些小细节错误,请原谅。)/P> < P>我在几个月前做了类似的事情,大约有3兆字节的代码,而你说“手工做它将是完全不起动器”,我认为这是唯一的方法。原因是您应该将override关键字应用于打算覆盖基类方法的原型。任何添加它的工具都将把它放在实际上覆盖基类方法的原型上。编译器已经知道那些方法是什么,所以添加关键字不会改变任何东西。(请注意,我对新标准不是很熟悉,我假设override关键字是可选的。Visual Studio至少从VS2005开始就支持override。)

我在头文件中搜索了“virtual”来查找其中的大部分,偶尔还会发现另一个原型缺少override关键字


我发现了两个bug。

Eclipse CDT有一个工作的C++解析器和语义实用程序。最新版本的IIRC还具有重写方法的标记


编写一个基于此的插件并重写代码以包含
override
标记(如果合适),不需要太多代码。

LLVM项目正在开发一个工具