首先,如果在头文件中定义一个普通的函数,比如下面这样,肯定会在程序链接的时候报“重复定义”的错误。
// 错误的版本,链接时会报重复定义错误
void DoSomething()
{
}
D:/kexin/untitled5/s.h:16: multiple definition of `DoSomething()'
CMakeFiles\untitled5.dir/objects.a(1.cpp.obj):D:/kexin/untitled5/s.h:16: first defined here
collect2.exe: error: ld returned 1 exit status
那么如果我们想在头文件中定义一些常用的函数,一般做法是在函数前加“inline”关键字,这样就不会报“重复定义”的错误了,并且能够像函数一样被其他的c/cpp源码文件调用了。
// inline版本,没有问题
inline void DoSomething()
{
}
这时候如果你在inline后面加入“static”关键字也是没问题的:
// inline static版本,也是没有问题
inline static void DoSomething()
{
}
区别是:加了static关键字后,每个调用它的c/c++源码文件都会有一个copy,即static其实是限制了函数的作用域在本源码文件内。
----------------------------------- 分割线 ----------------------------------------
那么另一个问题来了:如果我们在函数内部定义static变量时,会是怎么样的情况呢?
// 版本1:非static的inline函数内部定义static变量
inline void NonStaticInlineFunc()
{
static int localVar;
std::cout << "In NonStaticInlineFunc: localVar = " << (void*)&localVar << std::endl;
}
// 版本2:static的inline函数内部定义static变量
inline static void StaticInlineFunc()
{
static int localVar;
std::cout << "In StaticInlineFunc: localVar = " << (void*)&localVar << std::endl;
}
如果我们分别在1.cpp和2.cpp两个源码文件中分别调用这两个inline函数,可以通过结果看到区别。
// 1.cpp
void foo1()
{
std::cout << "Calling by foo1" << std::endl;
NonStaticInlineFunc();
StaticInlineFunc();
}
// 2.cpp
void foo2()
{
std::cout << "Calling by foo2" << std::endl;
NonStaticInlineFunc();
StaticInlineFunc();
}
程序运行结果:
Calling by foo1
In NonStaticInlineFunc: localVar = 0x4040b0
In StaticInlineFunc: localVar = 0x408044
Calling by foo2
In NonStaticInlineFunc: localVar = 0x4040b0
In StaticInlineFunc: localVar = 0x408054
可以看到:如果在inline后加了static关键字,则在函数中定义的static变量则会在每一个源码调用文件中产生了一个拷贝,而没加static关键字的inline函数则会产生一个全局的static变量。
具体解释参考https://stackoverflow.com/questions/185624/static-variables-in-an-inlined-function