【问题标题】:How to properly initialize global variables? [duplicate]如何正确初始化全局变量? [复制]
【发布时间】:2014-01-12 00:55:48
【问题描述】:

我正在编写一个小学生项目,但遇到的问题是我有一些全局变量,需要在一些源文件中使用它,但是我收到错误 undefined reference to variable_name。让我们创建三个源文件,例如:

tst1.h:

extern int global_a;
void Init();

tst1.cpp:

#include "tst1.h"
void Init(){
  global_a = 1;
}

tst2.cpp:

#include "tst1.h"
int main(){
  Init();
}

当我编译和链接时,这就是我得到的:

$ g++ -c tst1.cpp 
$ g++ -c tst2.cpp 
$ g++ tst2.o tst1.o
tst1.o: In function `Init()':
tst1.cpp:(.text+0x6): undefined reference to `global_a'
collect2: error: ld returned 1 exit status

如果我删除 extern 语句,那么我会遇到另一个问题,让我展示一下:

$ g++ -c tst1.cpp 
$ g++ -c tst2.cpp 
$ g++ tst2.o tst1.o
tst1.o:(.bss+0x0): multiple definition of `global_a'
tst2.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status

我确实需要一些全局变量,例如我的小项目使用汇编代码,并且有一个变量像 string rax = "%rax %eax %ax %ah %al";应该通过不同的源文件引用。

那么,如何正确初始化全局变量呢?

【问题讨论】:

  • 最好的解决方案是不使用全局变量。有关如何避免它们的提示:依赖注入。
  • @Tim,我知道,全局变量是不好的风格,但在某些情况下它是正确的方法。比如我的项目是汇编,那么很多文件应该知道CPU寄存器的名字,变量string rax = "%rax %eax %ax %ah %al";应该通过不同的源文件引用。
  • 一般来说,静态类成员应该是首选。

标签: c++ variables global-variables


【解决方案1】:

您只声明了变量但没有定义它。这条记录

extern int global_a;

是声明而不是定义。要定义它,您可以在任何模块中编写

int global_a;

或者按照下面的方式定义函数init会更好

int Init { /* some code */; return 1; }

在main函数之前的main模块中写

int global_a = Init();

【讨论】:

  • 正如我在下面评论的那样,编译器说tst1.cpp:2:5: error: redefinition of ‘int global_a
  • 很抱歉,我没有理解您的评论。我展示了一个相关的代码。不能简单的复制粘贴吗?
  • 我只是写在 tst1.cpp 中,在全局范围内 int global_a;。编译器给出错误。
  • 您应将声明保留在标题中。我写了你需要的东西。有什么问题?
  • 哦,对不起,我是个白痴 :) 我通过一些实验删除了extern 声明。没错。
【解决方案2】:

tst1.cpp 应该改为:

#include "tst1.h"

int global_a = 1;

void Init(){  
}

你也可以将初始化行写成:

int global_a(1);

或者在 C++11 中:

int global_a{1};

全局应该只在一个源文件中定义(即不带extern前缀),而在头文件中文件。

【讨论】:

  • 不,这就是我得到的:tst1.cpp:2:5: error: redefinition of ‘int global_a’ int global_a = 33; ^ In file included from tst1.cpp:1:0: tst1.h:1:5: error: ‘int global_a’ previously declared here int global_a; ^
  • 对不起,格式化。很快它就会说tst1.cpp:2:5: error: redefinition of ‘int global_a’
  • 我假设你的tst1.hextern int global_a;正如你在问题中所写的,不仅仅是int global_a;
  • 没错,但同时有两个正确答案。我选择了一个,哪个作者给我带来了答案。抱歉,虽然我想尝试过,但无法选择两个正确答案。
  • 没关系。当某人发布的代码与他们尝试构建的代码不同时,这很烦人。
【解决方案3】:

你需要添加

#ifndef TST1_H
#define TST1_H
.....
#endif 

到 tst1.h。它在 tst2.cpp 中包含两次

【讨论】:

  • 不,它没有包含两次,它被编译了两次(在不同的翻译单元中)。包含守卫不能解决这个问题。
猜你喜欢
  • 1970-01-01
  • 2019-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-14
  • 1970-01-01
相关资源
最近更新 更多