我有三个文件:
1。 Joy.h
class Joy
{
public:
void test();
};
2。 Joy.cpp
#include "Joy.h"
inline void Joy::test() {}
3。 main.cpp中
#include "Joy.h"
int main()
{
Joy r;
r.test();
return 0;
}
我尝试使用以下方法编译它们:
g++ cpp Joy.cpp
g ++说:
main.cpp:(.text+0x10): undefined reference to `Joy::test()'
谁能告诉我为什么......
如果我不想在.h文件中定义test()
函数但仍希望它是inline
函数,如何解决这个问题?
答案 0 :(得分:11)
当您定义内联成员函数时,您应该使用关键字inline前置成员函数的定义,并将定义放入头文件中。
当你基本上声明一个函数时你正在告诉编译器(如果可能的话)用调用函数的任何地方用函数的内容替换调用函数的代码。这个想法是函数体可能很小,调用函数比函数体本身更有开销。
为了能够做到这一点,编译器需要在编译调用函数的代码时看到定义,这实际上意味着定义必须驻留在头文件中,因为调用函数的代码只能访问头文件
好读:
的 [9.7] How do you tell the compiler to make a member function inline? 强>
答案 1 :(得分:4)
编译器需要函数的完整定义,以便它可以内联从中调用。只有在标题本身中定义它才有可能。
inline
功能如何运作?
说,你定义这个:
inline void increment(int &i) { ++i; }
然后将其用作:
int i = 0;
while( i < N )
{
std::cout << i << std::endl;
increment(i);
}
然后编译器将此代码转换为此(粗略地说):
int i = 0;
while( i < N )
{
std::cout << i << std::endl;
++i; //replaced the call with the equivalent code which the function
//actually executes to produce the same effect
//(edit typo) it replaces to ++i and not i++ as it was the original.
}
使用函数本身的代码替换函数调用被称为内联。你可以说,该函数是内联的。
请注意,inline
关键字只是编译器的提示:它告诉编译器如果可能内联我。无法保证编译器每次inline
函数调用都将被内联。
答案 2 :(得分:4)
从标准(N3242,7.1.2.4):
应在每个翻译单元中定义内联函数 它被使用,并且在每种情况下都应具有完全相同的定义。
请看这里:How do you tell the compiler to make a member function inline?
答案 3 :(得分:1)
由于C ++编译为单独编译单元(通常是每个cpp文件)的方式,一个cpp文件的编译不知道另一个编译单元中内联函数的实现,因此不能内联它。
解决方案是将内联函数的实现放在头文件中,这样使用头部的所有文件都可以访问实现,
答案 4 :(得分:0)
内联函数是一个函数,已要求编译器执行内联扩展。
因此,inline
function的重点在于在行中实现。如果您仍希望它是inline
函数,则无法在另一个源文件中定义它。