何时在C++中使用extern

Asl*_*986 372 c++ variable-declaration

我正在阅读"用C++思考",它刚刚介绍了这个extern声明.例如:

extern int x;
extern float y;
Run Code Online (Sandbox Code Playgroud)

我想我理解了意义(没有定义的声明),但我想知道什么时候它有用.

有人能提供一个例子吗?

dre*_*lax 477

当你有全局变量时,它会很有用.您在标头中声明了全局变量的存在,以便包含标头的每个源文件都知道它,但您只需要在其中一个源文件中"定义"它一次.

为了澄清,使用extern int x;告诉类型的对象,编译器int叫做x存在的地方.知道存在的位置并不是编译器的工作,它只需要知道类型和名称,以便知道如何使用它.一旦编译完所有源文件,链接器将解析x它在其中一个已编译源文件中找到的一个定义的所有引用.为了使它工作,x变量的定义需要具有所谓的"外部链接",这基本上意味着它需要在函数之外声明(通常称为"文件范围")并且不需要static关键字.

标题:

#ifndef HEADER_H
#define HEADER_H

// any source file that includes this will be able to use "global_x"
extern int global_x;

void print_global_x();

#endif
Run Code Online (Sandbox Code Playgroud)

来源1:

#include "header.h"

// it needs to be defined somewhere
int global_x;

int main()
{
    //set global_x here:
    global_x = 5;

    print_global_x();
}
Run Code Online (Sandbox Code Playgroud)

来源2:

#include <iostream>
#include "header.h"

void print_global_x()
{
    //print global_x here:
    std::cout << global_x << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

  • @Aslan986:不,更糟糕的事情发生了.包含标头的每个源文件都有*自己的*变量,因此每个源文件将独立编译,但链接器会抱怨,因为两个源文件将具有相同的全局标识符. (59认同)
  • 你不应该在标题中声明全局变量,因为当2个文件包含相同的头文件时,它将不会链接(链接器将发出有关"重复符号"的错误) (23认同)
  • 谢谢.那么,如果我在没有extern关键字的头文件中声明一个全局变量,那么包含头的源文件看不到它? (15认同)
  • 当你不使用"extern"这个词时,那么现在变量就存在了.当你使用"extern"时,它是"嘿,其他地方有这个var".很抱歉没有回答它是一个定义还是声明,因为我总是对这两个感到困惑. (7认同)
  • @CCJ:包含保护仅适用于包含它的源文件。它停止将同一标头包含在同一源文件中两次(以防其他标头也包含该标头等)。因此,即使有了包含保护,包含头的每个源文件仍将具有自己的定义。 (3认同)
  • @kuba:你的意思是声明还是定义? (2认同)
  • @Aslan986如果您“在不带 extern 关键字的情况下在头文件中声明全局变量”,那么您正在定义它而不是声明它。:) (2认同)
  • @dreamlax您能否用代码解释如果我们使用static修饰符会发生什么? (2认同)

MBy*_*ByD 147

在几个模块之间共享变量时,它非常有用.您可以在一个模块中定义它,并在其他模块中使用extern.

例如:

在file1.cpp中:

int global_int = 1;
Run Code Online (Sandbox Code Playgroud)

在file2.cpp中:

extern int global_int;
//in some function
cout << "global_int = " << global_int;
Run Code Online (Sandbox Code Playgroud)

  • 这个答案比接受的答案更正确,因为它没有使用头文件,它清楚地表明它只在少数模块之间共享时才有用.对于较大的应用程序,最好使用例如ConfigManager类. (32认同)
  • @Zac:另一方面,通过不在标题中声明全局变量,您无意中确定了确定实际定义位置的难度.通常如果你看到在`abc.h`中声明的全局变量,很有可能它会在`abc.cpp`中定义.一个好的IDE总能提供帮助,但组织良好的代码始终是更好的解决方案. (7认同)
  • 涉及命名空间时是否有任何问题,`global_int` 在全局命名空间中,如果我要在某个命名空间部分的 file2.cpp 中使用它,我必须正确地确定它的范围?即`命名空间XYZ{ void foo(){ ::global_int++ } };` (2认同)

Tre*_*vor 59

这完全取决于联系.

以前的答案提供了很好的解释extern.

但我想补充一点.

你问externC++ç,我不知道为什么没有答案提这个案子时,extern与来自const于C++.

在C++中,const变量默认具有内部链接(不像C).

所以这种情况会导致链接错误:

来源1:

const int global = 255; //wrong way to make a definition of global const variable in C++
Run Code Online (Sandbox Code Playgroud)

来源2:

extern const int global; //declaration
Run Code Online (Sandbox Code Playgroud)

它必须是这样的:

来源1:

extern const int global = 255; //a definition of global const variable in C++
Run Code Online (Sandbox Code Playgroud)

来源2:

extern const int global; //declaration
Run Code Online (Sandbox Code Playgroud)

  • 为什么它在c ++中工作时没有在定义部分中包含'extern'? (2认同)
  • 确认,在MSVS 2018中,如果`const int global = 255;`中省略了`extern`,则*是*链接错误. (2认同)

Mar*_*lon 13

当您想要一个全局变量时,这很有用.您可以在某个源文件中定义全局变量,并在头文件中将它们声明为extern,以便包含该头文件的任何文件都可以看到相同的全局变量.

  • 我不知道...要保持恒定的值听起来很费劲... (2认同)