如何在C ++中查找函数的所有调用者?

时间:2009-07-16 21:46:06

标签: c++ c refactoring function

我正在用C ++重构一些代码,我想弃用一些旧的方法。我目前找到所有方法的方法如下:

  1. 在我正在工作的源文件中注释掉原始方法。
  2. 尝试编译代码。
  3. 如果找到编译器错误,则在注释中注释注释并尝试重新编译。
  4. 编译成功完成后,我找到了所有的电话。
  5. 这完全糟透了。我也尝试过grepping source来获取函数调用的名称,但是我有时会遇到带有不同参数的同名函数的问题,所以我的编译让C ++编译器为我解析名称。我为C#找到了this question,但我的代码库完全用C ++实现。

    有没有更好的方法来查找C ++中类方法或函数的所有调用者?我在Unix系统上使用GCC,但跨平台解决方案将是最高级的。

9 个答案:

答案 0 :(得分:35)

GCC允许您使用__attribute__((deprecated))修饰变量,函数和方法,这将对所有被调用者发出警告(除非给出-Wno-deprecated-declarations)。

class A {
public:
    A() __attribute__((deprecated)) {}
};
int main() {
    A a;
}
$ g++ test.c
test.cc: In function ‘int main()’:
test.cc:6: warning: ‘A::A()’ is deprecated (declared at test.cc:3)

答案 1 :(得分:10)

Eclipse可以在没有任何插件的情况下完成此操作。即使您不想将它用于日常编辑器,它也可以成为这类工具的有用工具。

  1. 下载,安装并运行Eclipse CDT
  2. 转到File,New,C ++ Project下。输入项目名称,然后从“项目类型”树视图中选择“空Makefile”项目。取消选中“使用默认位置”,然后输入项目所在的文件夹。
  3. 单击“下一步”,然后单击“完成”。
  4. Eclipse将自动开始为您的项目编制索引。如果它确实是一个Makefile项目,并且因为你正在使用g ++,你可以完全清理然后在Eclipse中构建(在Project菜单下),它应该自动使用你现有的makefile并自动发现你的include目录和其他项目设置。
  5. 在源文件中找到重载函数的原型,右键单击它,选择“引用”,然后选择“项目”。 Eclipse将在项目中找到对该函数的所有引用,并且仅查找该函数的特定重载。
  6. 您还可以使用Eclipse的内置重构支持来重命名重载的函数,以便它们不再过载。 Eclipse也是完全跨平台的;即使对于在其他IDE中维护和构建的项目,您也可以使用索引器,搜索引用和重构等功能。

答案 2 :(得分:6)

一种选择是通过Cscope等程序运行整个项目。它基本上解析了项目的整个源代码,并构建了一个数据库,可以轻松搜索所有函数的调用者,所有引用等等。

我知道它对C来说效果很好,他们声称它适用于C ++。 KScope是它的KDE GUI前端。

答案 3 :(得分:4)

我认为您想要的是查看调用图。有关如何执行此操作的一些好建议,请参阅this question

答案 4 :(得分:4)

对于想在Windows下的Visual Studio中执行此操作的人....

视觉辅助非常好。它对许多C ++重构,调用图,重命名,自动创建头定义或生成方法等等都有很大帮助。它并不完美,不像Java / C#重构工具的质量,但对C ++真的很好!! / p>

答案 5 :(得分:3)

Eclipse的这个插件可能是正确的工具:CallGraph View

答案 6 :(得分:2)

这就是我的表现。如果你的代码全部在同一个地方,那么“grep”(或者发现| grep combo)也可以解决问题。

一个caviat:此方法经常会错过未有条件编译到当前配置中的实例。如果您的代码使用#ifdefs来支持多个配置,那么一个彻底的人将尝试使用每个配置进行编译以捕获所有实例。

答案 7 :(得分:2)

如果你让Eclipse CDT索引是你的源代码库,那么你应该能够查看任何函数的调用层次结构,甚至可以执行一些重构。

你可以download用于C / C ++开发人员的Eclipse IDE(希望你能为你的特定* NIX找到一个端口)并按照他们的instructions开始。

答案 8 :(得分:2)

在visual studio中,右键单击功能名称,然后单击“呼叫浏览器”>显示来电者图

然后在显示窗口中应该有一个名为“调用函数”的文件夹,其中包含调用该函数的所有位置,您可以在代码中双击它们中的每一个。