作者热门文章
- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
在我的实现文件(.cc 文件)中,我经常发现在类定义中定义成员函数很方便(例如 Pimpl 类的函数)。例如:
struct X::Impl {
void DoSomething() {
...
}
};
代替
struct X::Impl {
void DoSomething();
};
void X::Impl::DoSomething() {
...
}
出于几个原因,我认为这比在类定义之外实现函数更可取。它增强了可读性并促进了保持方法小的实践(通过使其易于添加)。代码也更易于维护,因为您永远不必更新方法声明。
我看到的唯一缺点是类声明中定义的方法是隐式内联的,这通常是不可取的,因为目标代码的大小会增加。
我的问题是:
我有这个权利吗?这种做法还有其他我遗漏的缺点吗?
隐式内联是否值得担心?编译器是否足够聪明,可以拒绝我对不应该内联的内联方法的隐式请求?
是否可以(通过编译器扩展或其他方式)声明类定义中定义的方法不被内联?
最佳答案
简单的回答是你不应该关心。在类定义中定义的成员函数是隐式内联
,但这并不意味着它们是内联(即代码不需要在调用位置内联)。
编译器实现者投入了大量时间和资源来提出启发式方法,根据函数的大小、复杂性以及是否可以内联来确定是否应该进行实际内联(递归函数不能内联[*])。编译器比我们大多数人拥有更多关于生成的代码及其运行架构的信息。相信它,然后如果您觉得可能存在问题,分析,如果分析表明您应该更改代码,那么就去做,但事后做出明智的决定。
如果要验证函数是否确实被内联,可以查看程序集并检查是否有对函数的调用或代码是否真的被内联。
[*] 如果编译器可以将递归转换为迭代,就像尾递归的情况一样,那么理论上可以内联转换后的函数。但是,无论如何,带有循环的函数被内联的可能性较小......
关于C++ - 避免类定义中定义的函数的隐式内联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10858458/
我是一名优秀的程序员,十分优秀!