.cpp与.h中的函数方法定义
Function method definition in .cpp vs .h
为了减少工作中相当大的框架的编译时间,我正在考虑将.h文件中的类方法定义移动到其关联的.cpp文件中,如果它们非常大或需要编译可以移动到关联.cpp文件的includes。为了清楚起见,下面是一个人为的例子(尽管Foo::inc
是一个很小的方法)
main.cpp:
#include "Foo.h"
int main(int argc, char** argv) {
Foo foo(argc);
foo.inc();
return foo.m_argc;
}
Foo.h之前(还不需要Foo.cpp):
class Foo {
public:
int m_argc;
Foo (int argc) : m_argc(argc) {}
void inc() { m_argc++; }
};
:之后的Foo.h
class Foo {
public:
int m_argc;
Foo (int argc) : m_argc(argc) {}
void inc();
};
Foo.cpp:
#include "Foo.h"
void Foo::inc() { m_argc++; }
很久以前,一位同事提到,在某些情况下,这可能会导致运行时性能下降。我在谷歌上寻找这个案例,但似乎找不到,这个问题的公认答案是我能找到的最接近的,但它没有给出这个案例,只是提到它可能发生:将内联方法从头文件移动到.cpp文件
顺便说一句,我对方法明确使用inline
的情况不感兴趣,我上面链接的答案是我能找到的最接近的答案
什么情况(如果有的话)会导致运行时间减慢?
您的原始方法void inc() { m_argc++; }
自动为inline
,因此允许编译器用内联版本替换调用。
一旦将方法从类定义移到模块中,该方法就不再是inline
,内联扩展也不会发生,标准方法调用也会出现,结果可能会更慢。
减少标头依赖性对于减少编译时间来说总是一个好主意。它是清单中最重要的项目之一,比如什么技术可以用来加快C++编译时间?
我建议——如果还没有完成的话——看看主要的参与者用评测C++编译过程来消耗你的编译时间
还有一些助手可以对include依赖项进行排序,请参阅C++中的自动化#include重构
关于将代码移动到源文件是否会降低运行时性能的问题:这取决于具体情况。一般来说,如果你在头中有函数,你可以说你给了编译器一个内联的机会。
我喜欢引用C++常见问题解答-Inlinein:
内联函数能提高性能吗
是的也不是。有时。大概
没有简单的答案。内联函数可能会生成代码更快,他们可能会让速度变慢。他们可能会制作可执行文件越大,它们可能会使它变小。他们可能会被鞭打可能会防止颠簸。他们可能是,而且经常是,完全与速度无关。
编译器(可能还有后来的链接器)对它做什么取决于您使用的编译器工具链以及您提供的编译器/链接器选项。
例如,查看内联时发生的所有事情-使用GNU编译器集合:
GCC在未优化时不内联任何函数。。。
一些参考文献:
- 内联速度和编译器优化
- 用于解析C++源代码并将头内联方法移动到.cpp源文件的工具
- C++优化技术-C++最终优化-内联函数
- 优化C++/编写高效代码/性能提升功能-内嵌函数
- C++优化技术
- 如何在 c++ 的类中递归调用函数方法?
- 通过构造函数方法输出的类到类类型转换是 5500 为什么不是 5555
- 在 *.cpp 文件中实现的 c++ 函数/方法永远不会内联扩展吗?
- 如果子类中没有构造函数方法,则错误"no matching function for call to 'LGame::LGame(String&)'"
- 指向类中函数方法的指针不起作用
- 如何发送通过绑定到函数/方法创建的函数对象?
- 编译错误,未创建函数/方法! 对于 brms 模型
- 对静态重载(类)函数/方法的调用是不明确的
- 复制构造函数方法的用法
- C/C++ 函数/方法与 Java 的公开
- std ::函数方法参考无法将dword投入到dword64
- 链表的析构函数方法
- 为什么在类构造函数方法中,std::string 参数在调试时显示不同的结果?
- 我的构造函数方法不接受参数(DirectX / Windows)
- 当函数/方法应该要求 * 或 &
- 带有常量构造函数参数的C++变量构造函数方法
- 使用模板递归检查函数方法是否存在
- 如何通过析构函数方法删除对象(类)
- 为什么在 Java 和 C++ 中不允许隐藏虚拟函数/方法?
- 在构造函数方法中返回一个子类