我知道根据定义,内联成员函数应该放在头中。但是,如果无法将函数的实现放入头文件中,该怎么办?让我们来看看这种情况:
文件A.h
#pragma once
#include "B.h"
class A{
B b;
};
文件B.h
#pragma once
class A; //forward declaration
class B{
inline A getA();
};
由于循环包含,我必须将getA
的实现放在
B.cpp
#include "B.h"
#include "A.h"
inline A B::getA(){
return A();
}
编译器会内联getA
吗?如果是,那么哪个内联关键字是有意义的(头中的关键字还是.cpp文件中的关键字)?有没有其他方法可以将内联成员函数的定义放到它的.cpp文件中?
发布于 2010-10-22 08:15:28
它不能,超出了B.cpp的作用域。编译器在每个编译单元的基础上操作,即它单独编译每个.cpp文件,所以如果它编译C.cpp,它将没有getA()的代码可用,并且需要执行函数调用并让链接器修复它(或者,如果它真的通过单词并尝试内联,它将以链接器错误结束。inline
具有与static
相似的特性)。
唯一的例外是LTCG,即链接时代码生成,它在较新的编译器上可用。
在这种情况下,一种方法是使用包含内联代码的另一个头文件(有时名为*.inl文件)。
编辑:至于哪个内联是相关的-它是类定义中的内联,也就是头文件中的那个。请记住,许多编译器都有自己的想法,即什么可以内联,什么应该内联。例如,gcc可以完全禁用内联(-O0),或者它可以内联任何它认为值得内联的东西(比如-O3)。
发布于 2010-10-22 09:02:43
我会从相反的方向做这件事。
不要给你的函数添加内联声明(除非你也需要)。
只有在头文件中但在类声明之外定义函数时,才需要将内联声明添加到函数/方法中。
X.h
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.
X.cpp
// Never declare anything inline in the cpp file.
int X::getZ() { return 6; }
给你更具体的例子。
删除所有内联规范。他们没有做你认为他们正在做的事情。
发布于 2010-10-22 08:28:13
如今,大多数编译器都可以在链接时和编译时执行内联。如果您的函数可能从内联中受益,那么链接时间优化器很可能会这样做。
当链接器到达它的时候,编译器输出的内联状态就不多了,除了编译器将某些对象标记为可收集之外,例如,因为内联函数或类模板实例出现在多个编译单元中,或者当多个符号共享一个名称时,它应该引发错误,例如main函数被定义了两次。所有这些都不会影响它将生成的实际代码。
https://stackoverflow.com/questions/3992980
复制相似问题