.cpp文件中的C++内联成员函数

Mat*_*Mat 69 c++ inline function member

我知道按定义,内联成员函数应该进入标题.但是如果不能将函数的实现放入标题呢?让我们来看看这种情况:

档案啊

#pragma once
#include "B.h"

class A{
    B b;
};
Run Code Online (Sandbox Code Playgroud)

文件Bh

#pragma once

class A; //forward declaration

class B{
    inline A getA();
};
Run Code Online (Sandbox Code Playgroud)

由于圆形包括我必须把实施getA

B.cpp

#include "B.h"
#include "A.h"

inline A B::getA(){
    return A();
}
Run Code Online (Sandbox Code Playgroud)

编译器会内联getA吗?如果是这样,哪个内联关键字是重要的(标题中的那个或.cpp文件中的那个)?是否有另一种方法将内联成员函数的定义放入其.cpp文件中?

Aru*_*run 67

引用C++ FAQ:

注意:必须将函数的定义({...}之间的部分)放在头文件中,除非该函数仅在单个.cpp文件中使用.特别是,如果将内联函数的定义放入.cpp文件中并从其他.cpp文件中调用它,则会从链接器中获得"未解析的外部"错误.

只要发现任何内联函数的使用,编译器就需要查看内联函数的定义.如果内联函数放在头文件中,这通常是可能的.

编译器内联getA吗?

不,除非使用getA()B.cpp本身.

如果是这样,哪个内联关键字是重要的关键字(标题中的那个或cpp中的那个)?

最佳实践:仅限于类体外的定义.

有没有其他方法将内联成员函数的定义放入其cpp文件中?

不,至少我不知道.


Ebo*_*ike 16

它不能超出B.cpp的范围.编译器在每个编译单元的基础上运行,即它单独编译每个.cpp文件,因此如果它编译C.cpp,它将没有getA()的代码可用,并且需要执行函数调用和让链接器修复它(或者,如果它确实让你接受了这个词并试图内联,它将最终出现链接器错误.inline具有类似的特性static).

唯一的例外是LTCG,即链接时代码生成,可在较新的编译器上使用.

在这种情况下,一种方法是使用包含内联代码的另一个头文件(有时命名为*.inl文件).

编辑:至于哪个内联是相关的 - 它是类定义中的那个,即在头文件中.请记住,许多编译器对可以和应该内联的内容有自己的想法.例如,gcc可以完全禁用内联(-O0),或者它可以内联任何它认为值得内联的内容(如-O3).


Mar*_*ork 8

我会从相反的方向去做这件事.

不要在函数中添加内联声明(除非你需要).

您需要将内联声明添加到函数/方法的唯一时间是在头文件中但在类声明之外定义函数.

XH

class X
{
    public:
        int getX()   { return 4;} // No inline because it is part of the class.
                                  // The compiler knows that needs an inline tag
        int getY();
        int getZ();
};

inline
int X::getY()  { return 5;}       // This needs to be explicitly declared inline.
                                  // Otherwise the linker will complain about
                                  // multiple definitions in compilation units.
Run Code Online (Sandbox Code Playgroud)

X.cpp

 // Never declare anything inline in the cpp file.

 int X::getZ() { return 6; }
Run Code Online (Sandbox Code Playgroud)

给你更具体的案例.
删除所有内联规范.他们没有做你认为他们正在做的事情.


Sin*_*ion 7

目前,大多数编译器都可以在链接时执行内联,以及编译时.如果你的函数可能从内联受益,那么链接时优化很可能做到这一点.

通过链接到达它的时候,没有多少有关编译器输出的在线状态可用,除了编译器就会某些对象为收藏,比如因为一个内联函数或类模板实例出现在多个编译单元,或当多个符号共享一个名称时,它应该引发错误,例如两次定义的主函数.这些都不会影响它将生成的实际代码.

  • 对于"最"部分,我不太确定.此外,LTCG速度非常慢,我个人希望能够更好地控制编译器的功能. (2认同)