在头文件中使用命名空间时的多重定义

时间:2016-11-09 19:54:42

标签: c++

我正在尝试在头文件global.h中定义全局命名空间。

...
namespace g {
   const int g_0 = 0;
   const int g_1 = 1;
}
...

当JUST #include "global.h"在其他.cpp文件中时,编译器会给出错误

multiple definition of g::g_0
multiple definition of g::g_1

例如,如果我尝试在其他.cpp文件中使用g_0g_1

int g_0_copy = g::g_0;
int g_1_copy = g::g_1;

它抛出错误说:

ISO C++ forbids in-class initialization of non-const static member...

使用命名空间声明全局变量时有什么特别之处吗? (在这种情况下我必须使用c ++ 98)

1 个答案:

答案 0 :(得分:3)

如果你的所有全局变量都是const,那么你很可能只需要包含守卫。

#ifndef   GLOBAL_H
#define   GLOBAL_H

...
namespace g {
   const int g_0 = 0;
   const int g_1 = 1;
}
...

#endif // GLOBAL_H

const global variables have internal linkage unless explicitly declared extern,因此只要每个翻译单元只定义一次,它们就不会导致链接错误。每个翻译单元都有自己的每个全局常量的副本,如果可能,编译器可能会优化或不优化。

但是,如果你的某些全局变量不是const,它会变得有点复杂。

#ifndef   GLOBAL_H
#define   GLOBAL_H

...
namespace g {
   const int g_0 = 0;
   const int g_1 = 1;

   int g_2 = 2; // Oh, boy.
}
...

#endif // GLOBAL_H

由于此变量默认具有外部链接,因此多个翻译单元包含名为g_2的不同变量会导致链接错误。这里的解决方案是在标头中声明变量extern,并将它们的实际定义放在源文件中。

// global.h
#ifndef   GLOBAL_H
#define   GLOBAL_H

...
namespace g {
   const int g_0 = 0;
   const int g_1 = 1;

   extern int g_2; // Oh, boy.
}
...

#endif // GLOBAL_H

// ---

// global.cpp
namespace g {
   int g_2 = 2;
}

也就是说,当SergeyA指出in the comments时,您收到的错误消息表明还有更多内容:

ISO C++ forbids in-class initialization of non-const static member...

我不知道有什么事情,不知道是什么代码导致它。