3

这之间的实际区别是什么

//Foo.h
struct Foo {
  void bar() {
    //lots of complex statements
  }
};

还有这个

//Foo.h
struct Foo {
  void bar();
};
//Foo.cpp
inline void Foo::bar() {
  //lots of complex statements
}

在最终编译的程序中,这两种方法是否有任何差异,或者是否保证相同?

还请根据良好的编码实践/经验就应该选择哪一个以及为什么做出一些评论。请注意“许多复杂的陈述”。这些东西实际上应该在头文件中的任何特定情况?AFAIK,大多数增强库都是仅标头的-他们为什么选择这样做?

4

2 回答 2

8

在最终编译的程序中,这两种方法是否有任何差异,或者是否保证相同?

两者都是一样的。
在类/结构体内部定义的成员函数是隐式的inline
但是,在第一个示例中,该函数可以inline在包含此标头的每个翻译单元中为 d。在第二个示例中,该函数只能内联在定义该函数的 cpp 文件中。这是因为编译器需要在函数调用时查看函数的定义以尝试使其内联。

要在评论中回答 Q:

假设您将函数的定义标记为inlinecpp 文件中A.cpp,并尝试从另一个 cpp 文件中调用此函数,B.cpp. 您最终会收到“未定义的外部符号”错误,这是因为在 C 和 C++ 中,每个翻译单元都是单独编译的,并且A.cpp在编译B.cpp.
如果仅从定义函数的位置调用该函数A.cpp,则该定义在同一个文件中可用,并且编译器和链接器很乐意编译并链接到它。

C++03 7.1.2 函数说明符:
第 3 段:

在类定义中定义的函数是内联函数。内联说明符不应出现在块作用域函数声明中。


就良好的编码实践/经验而言,应该选择哪一个?为什么?

类定义是作为类用户的接口。该接口的用户无需查看功能的实现细节。他们只需要看到如何使用这个接口。通过将函数定义(你提到的很长的一个)放在类中,你向用户提供了不必要的细节,从而使他们很难看到他们真正需要看到的内容.
解决此问题的最佳方法是:

  • inline在没有关键字 &的类定义中声明函数
  • 将带有关键字的函数定义放在inline类主体之外。

好读:
对于在类外部定义的内联成员函数,最好将 inline 关键字放在类主体内的声明旁边,或者放在类主体外部的定义旁边,还是两者兼而有之?


AFAIK,大多数增强库都是仅标头的-他们为什么选择这样做?

大多数 Boost 库都是模板库,对于基于模板的库,编译器需要在使用时查看定义,因此模板函数需要内联。
好读:
为什么模板只能在头文件中实现?

于 2013-02-10T12:34:11.897 回答
2

就其功能而言,这两者是相等的。但是,后者只能内联到Foo.cpp文件中。

于 2013-02-10T12:38:15.773 回答