命名空间重定义问题
1.起因
在命名空间里面定义了一些变量,但是编译不过,说是有重定义问题
代码是这样的,在另外两个cpp文件里用到了这个头文件,造成了这个问题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// a.h
namespace LinesInfoFunc
{
void func1();
void func2();
std::vector<OdDbMTextFragment> vecOdDbTextFrag;
std::vector<CString> vLineStr;
std::map<int, CString> mParagraph;
std::map<int, CString> mLineSpacing;
};
// b.cpp
#include "a.h"
// c.cpp
#include "a.h"
2.解决方法
在声明变量时加上extern,同时在cpp里面实现定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// a.h
namespace LinesInfoFunc
{
void func1();
void func2();
extern std::vector<OdDbMTextFragment> vecOdDbTextFrag;
extern std::vector<CString> vLineStr;
extern std::map<int, CString> mParagraph;
extern std::map<int, CString> mLineSpacing;
};
// a.cpp
namespace LinesInfoFunc
{
std::vector<OdDbMTextFragment> vecOdDbTextFrag;
std::vector<CString> vLineStr;
std::map<int, CString> mParagraph;
std::map<int, CString> mLineSpacing;
};
3.问题分析
命名空间只不过是为了不让名字重复,而在两个cpp里面都调用了头文件,相当于这些变量被定义了两次,就类似于你是这样写的
1
2
std::vector<int> sss;
std::vector<int> sss;
这样就会报重定义错
直接用最开始的代码写,就相当于声明并定义,虽然你并没有定义,但是会自动初始化的。
而加完extern就是只声明不定义,这样其他cpp引用了头文件,就不会有重定义的情况。
网上看到的: extern关键字用来声明变量,或者函数名以及对象名在其他文件中已经定义过,它通常只是起到一个说明的作用,只是告诉编译器这个变量来自其他文件,编译器会根据这个它提供的变量和名字在其他文件中查找
可以看这个链接每日一问3: C++中extern关键字的作用
里面提到:
在介绍extern之前,我们需要了解一下变量的声明和定义。变量的声明指向程序表名变量的类型和名字,即使得名字为程序所知,一个文件如果想使用别处定义的名字则必须包含对那个名字的声明。而变量的定义指申请存储空间,并将其与变量名相关联,除此之外,还可以为变量指定初始值。在程序中变量可以声明多次,但只能定义一次。一般而言,定义就是声明。但C++中由于extern的缘故,变量的声明和定义是可以分开的。凡是没有带extern的声明同时也都是定义。
本文由作者按照 CC BY 4.0 进行授权