内联函数和类和头文件

时间:2013-04-07 17:44:31

标签: c++ class inline one-definition-rule

  1. 头文件中定义的任何函数是否会自动内联?
  2. 如果我在一个类中声明一个函数并使用关键字内联给出定义,那么这个函数是否内联?如果是这样,为什么这不违反法律规定,内联职能应该在声明中给予机构?

3 个答案:

答案 0 :(得分:7)

类定义中定义的任何函数都是内联的。标记为inline的任何函数也都是内联函数。

class C {
    int f() { return 3; } // inline
    int g();
    int h();
}


inline int C::g() { return 4; } // inline
int C::h() { return 5; } // not inline

如果所有这些代码都在标题中并且该标题用于多个翻译单元,那么您会收到C::h有多个定义的投诉。 C::fC::g可以,因为它们是内联的。这是inline这些天的主要作用:允许在多个地方定义相同的功能(假设定义“相同”)。

答案 1 :(得分:4)

  

是头文件中定义的任何函数都会自动内联吗?

不,你应该用手内联在类体之外定义任何函数。否则,您很可能会遇到ODR违规行为(如果在多个翻译单元中包含标题)。

ISO C ++ 11

  

3.2一个定义规则

     

1:任何翻译单元都不得包含任何变量,函数,类类型,枚举类型或模板的多个定义。

     

[...]

     

4:每个程序应该只包含每个非内联函数的一个定义或该程序中使用的变量;无需诊断。该定义可以在程序中明确显示,可以在标准或用户定义的库中找到,或者(在适当的时候)隐式定义(见12.1,12.4和12.8)。内联函数应在每个使用它的翻译单元中定义。


  

如果我在一个类中声明一个函数并使用关键字inline给出定义,那么这个函数是否内联?如果是这样,为什么这不违反法律规定,内联职能应该在声明中给予机构?

有几种方法可以内联成员函数:

首先,根据7.1.2 / 3:

  

在类定义中定义的函数是内联函数。内联说明符不应出现在块作用域函数声明中.90如果在友元声明中使用内联说明符,则该声明应为定义,或者该函数应先前已内联声明。

struct First
{
    void first(){}
};

第二,第三和第四,根据9.3 / 3:

  

内联成员函数(无论是静态还是非静态)也可以在其类定义之外定义,提供类定义中的声明或类定义之外的定义将该函数声明为内联。 [注意:命名空间范围内的类的成员函数具有外部链接。本地类的成员函数(9.8)没有链接。见3.5。 - 后注]

struct STF
{
    void second();
    inline void third();
    inline void fourth();
};

inline void STF::second(){}
void STF::third(){}
inline void STF::fourth(){}

答案 2 :(得分:1)

inline是一个“提示”,只要编译器不必遵守它。它可以使内联不标记为内联而不必内联您标记为内联的内容。

由此,我的意思是你不应该依赖它。许多人建议您甚至不要使用它,因为它具有误导性。大多数现代编译器完全忽略它。

唯一的实际用途是允许您将静态实现放入标头中。这是否是一件好事是有争议的。