在我的实现文件(.cc文件)中,我经常发现在类定义中定义成员函数(例如Pimpl类的函数)是很方便的。例如:
struct X::Impl {
void DoSomething() {
...
}
};而不是
struct X::Impl {
void DoSomething();
};
void X::Impl::DoSomething() {
...
}我认为这比实现类定义之外的函数更可取,原因有几点。它增强了可读性,并便利了将方法保持较小的实践(通过使添加它们变得容易)。代码也更易于维护,因为您从来不需要更新方法声明。
我看到的唯一缺点是类声明中定义的方法是隐式内联的,这通常不可取,因为对象代码的大小增加了。
我的问题是:
发布于 2012-06-01 23:23:31
我不知道如何防止内衬,但GCC可以使用属性。例如:
struct X::Impl {
void DoSomething() __attribute__((noinline)) {
...
}
};发布于 2012-06-01 23:44:57
将您的内联选择所节省的所有CPU时间加起来。花的钱比你自己的少。线性路径长度的担忧是因为现在每天要处理数万亿次的处决。在L1中,40亿已经接近每秒了。250次,不是五分钟。如果没有人抱怨性能,那么您和您的编译器的选择至少是正确的。
对可读性的看法大不相同。重要的是你的听众的意见。
发布于 2012-06-01 23:46:58
一般来说,编译器会将它喜欢的东西内联起来,而且它不会太注意程序员给出的任何inline关键字。inline通常与static的治疗方式大致相同。
例如,递归函数通常不能完全内联(您想内联的函数体将再次包含一个应该内联的调用)。要测试特定编译器的行为,可以定义如下类:
class Fib {
public:
int calc(int i);
};
int Fib::calc(int i) {
if (i > 1)
return calc(i-1) + calc(i-2);
return 1;
}使用此定义,如果编译器感到有义务内联所有对calc的调用,则像下面这样的示例程序将无法在合理的时间或大小内编译
#include "tst.hpp"
#include <iostream>
int main() {
Fib f;
std::cout << f.calc(1000) << std::endl;
};因此,您可以通过编译此程序来测试编译器的行为。如果编译成功,编译器不会内联所有对Fib::calc的调用。
https://stackoverflow.com/questions/10858458
复制相似问题