【问题标题】:Multiple definition when using namespace in header file在头文件中使用命名空间时的多重定义
【发布时间】:2016-11-09 19:54:42
【问题描述】:

我正在尝试在头文件 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)

【问题讨论】:

  • 如果命名空间在同一个编译单元中包含两次,编译器会报错。否则常量有静态链接。
  • 愚蠢的问题。你在标题中包含守卫吗?
  • 需要完整代码。关于in-class initialization 的注释告诉我,您向我们展示的内容不止于此。
  • @StoryTeller xD。愚蠢的问题。

标签: c++


【解决方案1】:

如果你所有的全局变量都是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...

对此我无话可说,不知道是什么代码造成的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-12
    • 1970-01-01
    • 2016-12-17
    • 1970-01-01
    • 1970-01-01
    • 2015-08-05
    • 2013-01-12
    • 2020-05-15
    相关资源
    最近更新 更多