86
public:
     inline int GetValue() const {
          return m_nValue;
     }
     inline void SetValue(int nNewValue) {
          this -> m_nValue = nNewValue;
     }

Learn C++上,他们说它会运行得更快。所以,我认为在 getter 和 setter 上使用会很棒。但也许,它有一些缺点?

4

11 回答 11

75

在分析器明确告诉我不内联会导致性能问题之前,我不会内联任何内容。

C++ 编译器非常聪明,几乎可以肯定会自动为您内联这样简单的函数。通常它比你更聪明,并且会更好地确定应该或不应该内联的内容。

我会避免考虑内联或不内联什么,而是专注于解决方案。稍后添加inline关键字(这不是内联 BTW 的保证)非常容易,并且可以使用分析器轻松找到潜在位置。

于 2010-06-10T18:25:08.310 回答
32

如果您将它们写在定义中,则inline 默认情况下会考虑它们。

这意味着它们将被允许在多个编译单元中使用(因为类定义本身通常出现在多个编译单元中),而不是它们实际上会被内联。

于 2010-06-10T18:26:13.367 回答
16

这是公共 API 中的不良做法 对这些函数的任何更改都需要重新编译所有客户端。

一般来说,拥有 getter 和 setter 会表现出很差的抽象性,不要这样做。如果您经常访问另一个类中的原始数据,那么您可能需要重新安排您的类,而不是考虑您希望如何在一个类中操作数据并为此提供适当的方法。

于 2010-06-10T18:27:44.063 回答
11

负面观点:

  1. 编译器可以随意忽略你。

  2. 对这些函数的任何更改都需要重新编译所有客户端。

  3. 一个好的编译器会在适当的时候内联非内联函数。

于 2010-06-10T18:25:44.820 回答
5

我还想补充一点,除非您每帧执行数百万次获取/设置,否则这些是否内联几乎无关紧要。老实说,不值得为此失眠。

另外,请记住,仅仅因为您将“内联”一词放在声明+定义的前面,并不意味着编译器会内联您的代码。它使用各种启发式方法来确定它是否有意义,这通常是速度与大小的经典权衡。然而,在 VC++ 中至少存在蛮力“__forceinline”关键字(我不确定它在 GCC 中是什么),它踩踏了编译器的奇特启发式方法。我真的完全不推荐它,而且一旦你移植到不同的架构,它很可能是不正确的。

尝试将所有函数定义放在实现文件中,并保留头文件的纯声明(当然,除非您是模板元编程(STL/BOOST/等),在这种情况下,几乎所有内容都在头文件中;))

人们喜欢内联的经典位置之一(至少在我来自的视频游戏中)是数学标题。交叉/点积、向量长度、矩阵清除等通常放在标题中,我只是认为这是不必要的。9/10 它对性能没有影响,如果你需要做一个紧密的循环,比如用一些矩阵转换一个大的向量数组,你最好手动做数学内联,或者更好地编码它特定于平台的汇编程序。

哦,还有一点,如果你觉得你真的需要一个类来比代码更多的数据,考虑使用好的旧结构,它不会带来抽象的 OO 包袱,这就是它的用途。:)

抱歉,我不是故意的,但我只是认为考虑现实世界的用例会有所帮助,而不是过于拘泥于迂腐的编译器设置(相信我,我去过那里;))

祝你好运。

谢恩

于 2010-06-10T23:43:51.947 回答
3

通过将代码放在标题中,您将暴露您的内部类工作。客户可能会看到这一点,并对您的课程如何运作做出假设。这会使以后在不破坏客户端代码的情况下更改类变得更加困难。

于 2010-06-10T18:30:11.720 回答
2

代码编译时间会稍微长一些,你会失去封装。一切都取决于项目的规模及其性质。在大多数情况下,如果它们没有任何复杂的逻辑,则可以将它们内联。

顺便说一句,inline如果您直接在类定义中实现,您可以跳过。

于 2010-06-10T18:24:32.570 回答
2

inline 关键字在您的情况下没有意义

无论关键字如何,编译器都会内联您的函数,如果它可以并且想要的话。

关键字 inline 影响链接而不是内联。这有点令人困惑,但请阅读它。

如果定义位于与调用不同的编译单元(基本上是预处理器之后的源文件)中,则只有在启用整个项目优化和链接时间代码生成的情况下才能进行内联。启用它会大大增加链接时间(因为它实际上会重新编译链接器中的所有内容),但显然可以提高性能。不确定在 GCC 和 VS 中它是默认打开还是关闭。

于 2015-12-01T14:11:50.887 回答
1

我会说你不需要为此烦恼。阅读有关内联的常见问题解答部分

于 2010-06-10T18:28:14.503 回答
1

不需要,开始信任编译器,至少对于这样的优化!
“但不总是”

于 2010-06-10T20:23:58.587 回答
1

我得说,我对这种做法没有强烈的反感,就像这个线程上的其他人似乎有的那样。我同意,除了最常用的情况外,内联的性能增益在所有情况下都可以忽略不计。(是的,我在实践遇到过这种情况。)在我做这种内联的地方,我这样做是为了方便,通常只是为了这样的单行。在我的大多数用例中,如果我改变它们,避免在客户端重新编译的需求并不是那么强烈。

是的,您可以删除inline,因为它是由实现的位置所暗示的。

此外,我对访问者的激烈程度感到有些惊讶。你几乎不能对任何 OO 语言的类打喷嚏而不吹嘘一些,它们毕竟是一种从接口抽象实现的有效技术,因此将它们称为糟糕的 OO 实践有点自虐。最好不要随意编写访问器,但我建议您不要因热衷于消除它们而忘乎所以。

拿那个,纯粹主义者。:-)

于 2010-06-11T02:04:28.693 回答