.h中定义的函数有函数体,多个使用者就会有重复定义?
我做了一个很简单的实验,一个.h文件中一个class定义,有函数体代码,一个c风格函数,如下:$cat testInline.h
#pragma once
class C{
public:
void f(){}
};
void g(){}
然后有两个使用者:
$cat use01.cpp
#include"testInline.h"
void g01(){
g();
C obj1;
obj1.f();
}
$cat use02.cpp
#include"testInline.h"
int main(){
g();
C obj2;
obj2.f();
return 0;
}
如果联合编译use01和use02来生成一个可执行文件,那么会有编译错误
$g++ use01.cpp use02.cpp
duplicate symbol __Z1gv in:
/var/folders/zv/b953j0_55vldj97t0wz4qmkh0000gn/T/use01-34f300.o
/var/folders/zv/b953j0_55vldj97t0wz4qmkh0000gn/T/use02-838e05.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
很奇怪:
我在头文件中已经有了#pragma once,都不能阻止这个所谓的重复定义(__Z1gv是全局函数g())
然后我在testInline.h当中把g()的定义修改成了
inline void g(){}
这样就好了! 不是说inline关键字没有什么用的吗,编译器会自行决定是否内敛一个函数呢?
而且,为什么class C的函数f有了函数体,不报重复定义的错误(也不需要加inline)。而g()这个函数会报重复定义的错误除非我加上inline呢?
希望我的问题表述清楚了,请解惑。
所以你才需要inline 回复 2# windoze
为何C::f()不需要inline而::g()需要inline呢?
回复 1# cdsfiui
1. #pragma once 是用来防止头文件在一个编译单元(源文件)中被重复包含的;
2. inline 当然是有用的啦,在不加优化选项的情况下,编译器未必会自动内联函数;
3. class C 中定义的 member function 默认就是内联的。
回复 4# MMMIX
inline不光是优化选项,而且还标明该函数是weak symbol,允许多次出现在不同的compilation unit里。
页:
[1]