特性与问题验证
static函数的作用域为当前文件,如果仅将static函数/变量定义到头文件中,而该头文件被不同的文件引用
这并不会发生multiple define的错误,其原因在于对于两个文件而言,在引用头文件后存在独立的static函数,只是名字一样而已。
测试:
- 使用两个文件引用相同头文件(只有static&&不加预编译指令)
- 使用两个文件引用相同头文件(有其他变量&&不加预编译指令)
- 使用两个文件引用相同头文件(有其他变量&&加预编译指令)
- 两种修正方法与相关知识点
- 问题
1. 使用两个文件引用相同头文件(只有static&&不加预编译指令)
头文件:fun_static.h
// #ifndef FUN_STATIC_H
// #define FUN_STATIC_H
#include <iostream>
using namespace std;
static int count1 = 0;
static void func(int count){
static int count2 = 0;
cout << "this is a static function 第" << count << "次调用" <<endl;
cout << "count1为在fun_static.h文件中定义的静态变量 "<< count1 << endl;
cout << "count2为在fun_static.h文件定义的静态函数func中定义的静态局部变量 "<< count2 << endl;
count1++;count2++;
}
// #endif
两个.cpp文件:b.cpp 与 c.cpp
/*文件b.cpp*/
#include "fun_static.h"
static int a = 5;
static int count = 1;
void b_fun(void){
func(count);
}
/*文件c.cpp*/
#include "fun_static.h"
static int count = 0;
extern void b_fun(void);
int main(void)
{
func(count);
b_fun();
return 0;
}
运行结果与说明:
main | 调用头文件中的func函数 、调用外部引用的b.cpp文件中的b_fun函数。 |
---|---|
func函数 | 头文件中定义的static函数 |
b_ fun函数 | b.cpp中定义的static函数 |
count1 | 头文件中定义的静态变量 |
count2 | 头文件中静态函数func中定义的静态变量 |
count | 两个cpp文件中分别定义的静态变量 |
主要分析
count1说明头文件中的静态变量count1在两个函数中被调用时,并非指向同一变量地址,静态变量没有变化
count2进一步说明,函数地址也不同。
2.使用两个文件引用相同头文件(有其他变量&&不加预编译指令)
只需将.h文件中的count1修改为非静态变量、func修改为非静态函数
// #ifndef FUN_STATIC_H
// #define FUN_STATIC_H
#include <iostream>
using namespace std;
int count1 = 0;
void func(int count){
static int count2 = 0;
cout << "this is a static function 第" << count << "次调用" <<endl;
cout << "count1为在fun_static.h文件中定义的静态变量 "<< count1 << endl;
cout << "count2为在fun_static.h文件定义的静态函数func中定义的静态局部变量 "<< count2 << endl;
count1++;count2++;
}
// #endif
执行结果:这俩东西都multiple define了。
3.使用两个文件引用相同头文件(有其他变量&&加预编译指令)
将上面的.h文件中的预编译注释删除,还是会报错
其原因在于,对于C++来说,编译过程是独立进行的,生成.o文件后进行链接时,变量和函数已经发生了重定义。
4. 两种修正方法与相关知识点
4.1 使用Inline内联函数
内联函数可以被重定义,这是编译器允许的,因为其本质是在对函数代码进行替换,而不是单独编译通过链接器把地址连上。
头文件fun_static.h
#ifndef FUN_STATIC_H
#define FUN_STATIC_H
#include <iostream>
using namespace std;
static int count1 = 0;
inline void func(int count){
static int count2 = 0;
cout << "this is a static function 第" << count << "次调用" <<endl;
cout << "count1为在fun_static.h文件中定义的静态变量 "<< count1 << endl;
cout << "count2为在fun_static.h文件定义的静态函数func中定义的静态局部变量 "<< count2 << endl;
count1++;count2++;
}
#endif
而变量若不增加文件只能是使用static。
可以看出,count2发生变化,这是由于从最初的static变成inline后,不会单独分配空间了。
相关知识点如果不清楚可以看这个:头文件相关
4.2 使用单独的文件进行定义
fun_static.h
#ifndef FUN_STATIC_H
#define FUN_STATIC_H
#include <iostream>
using namespace std;
extern int count1;
void func(int count);
#endif
fun_static.cpp
#include "fun_static.h"
int count1 = 0;
void func(int count){
static int count2 = 0;
cout << "this is a static function 第" << count << "次调用" <<endl;
cout << "count1为在fun_static.h文件中定义的静态变量 "<< count1 << endl;
cout << "count2为在fun_static.h文件定义的静态函数func中定义的静态局部变量 "<< count2 << endl;
count1++;count2++;
}
关于外部引用extern的使用可以看extern相关文
问题
为什么使用inline和使用两个文件时,count1作为头文件中的静态变量,没有生成两个副本,而是被改变了数值。(期望大神解答)