【问题标题】:global extern const clarification全局外部常量说明
【发布时间】:2010-12-28 15:33:10
【问题描述】:

是在头文件中声明 extern const 还是只是 extern 相同的东西?也都会给外部链接?

globals.cpp

#include <string>

extern const std::string foo = "bar";

globals.h

#ifndef GLOBALS_H
#define GLOBALS_H

#include <iostream>

extern const std::string foo;

#endif  /* GLOBALS_H */

globals.h

#ifndef GLOBALS_H
#define GLOBALS_H

#include <iostream>

extern std::string foo;

#endif  /* GLOBALS_H */

编译和运行都很好,在多个文件中使用时都给出相同的地址,哪个更正确?

【问题讨论】:

  • 这不是哪个“更正确”的问题;其中之一实际上是不正确的,如果实际使用 foo 将导致错误。请参阅下面的答案。
  • 我在其他文件中做了 cout foo.c_str(),仍然编译和运行良好.. 很奇怪。
  • 这似乎是错误的。要么发生了更复杂的事情,要么你的编译器/链接器没有很好地检查声明。如果您尝试从这些文件之一修改 foo 会发生什么?例如是否 foo.clear();编译好吗?如果是这样,如果您在标头中使用“const”版本,它仍然可以编译吗? (如果它仍然可以编译,那么它可能不是文件看到的标头声明。)

标签: c++ global-variables constants extern


【解决方案1】:

这个是对的,

//globals.h

extern const std::string foo; //Consistent

一致!

【讨论】:

  • 在这种情况下,我应该在哪里初始化 foo?
  • .cpp文件中;此外,.cpp 文件中不需要extern
  • 很抱歉,我正在努力解决问题,.cpp 文件中的 foo = "abs" 之类的东西是否有效?如果不是那么我应该如何初始化它。还有一件事,extern 是否只用于类?
  • 没有。 const std::string foo = "abs"; 在同一命名空间级别。
【解决方案2】:

正确的是

extern const std::string foo;

foo 是定义它的源文件中的常量字符串,因此extern 声明也应表明这一点,并允许编译器捕获包含该标头的源文件中的代码可能尝试修改的实例foo.

【讨论】:

  • 感谢您的快速回答和解释 :)
【解决方案3】:

它们都编译得很好的唯一原因是您实际上并没有使用 foo,因此链接器是否可以找到 foo 并不重要(它从不尝试)。 (或者你的编译器/链接器是垃圾。:))

一致的标题很好。如果某些东西试图使用 foo,那么缺少 const 的那个不是并且将/应该导致错误。

如果您制作了一些包含 globals.h 的文件(不是 globals.cpp)并尝试使用 foo(例如,只需在函数中添加一行“foo.c_str();”),那么您将获得一个链接错误,因为找不到const std::string foo

这也是必须的。标头告诉任何想要使用 foo 的东西,它只能读取它,不能修改它。包含 globals.h 标头的内容不知道 globals.cpp 中的内容;如果您希望他们将对象视为 const,则必须将该信息放入他们包含的文件中。

【讨论】:

    【解决方案4】:

    您可以像您的示例一样提供 const 外部链接,但它仍然是不可修改的(常量)。 附:你需要包括&lt;string&gt;,而不是&lt;iostream&gt;

    附言如果我不清楚,您将无法重新定义 const-ness。这不会编译:

    extern std::string foo;
    extern const std::string foo = "bar";
    

    【讨论】:

    • 这就是我们想要的。但是哪个头文件是正确的?我放置 iostream 以便它同时包含 std::string 和 std::cout 的原因,我想更方便。
    • 你是什么意思,哪个是正确的?两者都是正确的,前提是您始终使用 const 或 non-const。你不能在一个地方定义 const 而在另一个地方定义 non-const。
    • iostream 不必包含字符串头
    • @Kaizoku,仅仅因为它编译并不能使它正确,也不意味着它可以正常工作甚至在其他环境中编译。举个简单的例子,“int *p = NULL; *p = 10;”可能编译得很好(除非编译器足够聪明地捕捉到它)但是如果你运行它会崩溃。
    【解决方案5】:

    对于 C 语言,在 .c 文件中声明实际的 const 并在头文件 (.h) 中为其使用“extern”。这应该和我们在声明全局变量时一样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-07
      • 2016-05-19
      相关资源
      最近更新 更多