头文件中定义变量
ZeroJiu 愚昧之巅V4

群体人性泯灭。

有时候需要在头文件中定义一些变量,需要注意一些点来避免重复定义的错误。

一个错误的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
/* test.h */
namespace n
{
int x = 1;
}

/* source1.cpp */
#include "test.h"
void process1(){ }

/* source2.cpp */
#include "test.h"
void process2() {}

编译上面代码,编译器会给出错误:

1
2
1>Source2.obj : error LNK2005: "int n::x" (?x@n@@3HA) already defined in Source2.obj
1>...\Test.exe : fatal error LNK1169: one or more multiply defined symbols found

出现上面错误是因为source1.cppsource2.cpp都包含了头文件test.h,导致int n::x被重复定义。

解决方案

使用extern关键字将变量定义编程变量声明。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* test.h */
namespace n
{
extern int x;
}

/* source1.cpp */
#include "test.h"
namespace n
{
int x = 1;
}
void process1(){ }

/* source2.cpp */
#include "test.h"
void process2() {}

编译上面一段代码是没有问题。在解决这个问题的基础上,我们考虑下下面的问题:

哪些场景下,可以头文件中定义变量?

头文件重定义变量——const变量

1
2
3
4
5
6
7
8
9
10
11
12
13
/* test.h */
namespace n
{
const int x = 1;
}

/* source1.cpp */
#include "test.h"
void process1(){ }

/* source2.cpp */
#include "test.h"
void process2() {}

在头文件中定义常变量并不会出现重定义问题,这是因为:

默认情况下,const对象被设定为仅在文件内有效。

当多个文件出现了同名的const变量时,其实等同于不同文件中分别定义了独立的变量。如果需要共享一个const变量,则需要使用extern关键词。

使用extern关键词,我们能在一个文件里定义const,在其他使用该变量的文件里声明const变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* test.h */
namespace n
{
extern const int x;
}

/* source1.cpp */
#include "test.h"
namespace n
{
const int x = 1;
}
void process1(){ }

/* source2.cpp */
#include "test.h"
void process2() {}

头文件重定义变量——static变量

1
2
3
4
5
6
7
8
9
10
11
12
13
/* test.h */
namespace n
{
static int x = 1;
}

/* source1.cpp */
#include "test.h"
void process1(){ }

/* source2.cpp */
#include "test.h"
void process2() {}

static变量和const变量类似,被多个源文件包含后其实是会存在多个独立的变量,static变量无法做到在多个源文件之间传递数据的效果。

总结

除了静态变量和常变量,不可以在头文件中定义变量,否则会导致重定义。在头文件中定义静态变量和常变量,其作用域会被限制在包含该头文件的源文件内。

Powered by Hexo & Theme Keep
This site is deployed on
Unique Visitor Page View