C++多文件中的全局变量

13

我有一些代码分布在三个文件中,我想使用第四个“全局”文件来存储一些物理常数,比如圆周率的值。这将避免重复定义 pi = 4*atan(1.0)。经过查找,我尝试创建一个全局头文件:

/*globals.h*/
extern double g_pi;

还有一个全局的cpp文件:

/*globals.cpp*/
#include "math.h"
#include "globals.h"
double g_pi = 4*atan(1.0);

然后我将这些文件包含在我的主文件中:

/*mainFile.cpp*/
//Include math and other libraries 
#include globals.h"
int main() {
/*
....
*/
double x = 2*g_pi
/*
....
*/
}

在 Ubuntu 上使用 g++ 编译器时,我遇到了对 g_pi 的未定义引用错误。希望这是一个简单的修复!非常感谢您的建议。如果需要更多细节,我很乐意提供。


问题可能出在你构建可执行文件的方式上,所以你应该将用于构建的工具(Makefile、g++命令行等)添加到你的问题中。 - alexisdm
你能否包含你执行编译的确切命令?以及确切的错误信息? - JaredC
5个回答

18
你可以简单地使用 `` 中的 M_PI 常量(还有其他常量)。
编辑:你的设置是正确的。我得到了一个可行的最小示例:
globals.h
extern double g_tst;

globals.cpp

#include "globals.h"
double g_tst = 4.0;

主函数.cpp

#include "globals.h"
#include <stdio.h>
#include <stdlib.h>

int main()
{
fprintf (stderr, "g_tst  = %lf \n", g_tst);
return 0;
}

问题出现在你的构建系统中。

请参考维基百科


7
我认为问题在于你写成了#include gobals.h而不是#include globals.h。这会导致未定义的引用,因为它没有插入globals.h。C++预编译器在找不到头文件时不会失败。相反,在编译时你会收到未定义的引用消息。

2
尝试将全局对象文件作为最后一个链接可能是问题的原因。

1
不可能是问题。链接器必须处理任何顺序,因为C++允许全局变量的双向使用。例如,A.cpp定义了int a并使用了b,而B.cpp使用了a并定义了int b。这必须链接,显然一个文件必须在链接顺序中先于另一个文件。 - MSalters

1

在一个翻译单元中,g_pi不得声明为extern。您可以使用一个小的#define来解决这个问题。

在globals.cpp中。

#define MY_EXTERN_CPP

在/*globals.h文件中

#ifdef MY_EXTERN_CPP
    #define MY_CONFIGURATION_EXTERN
#else
    #define MY_CONFIGURATION_EXTERN extern
#endif

MY_CONFIGURATION_EXTERN double g_pi;

所以,除了globals.cpp之外,你在所有包含它的翻译单元中都会将g_pi声明为extern。


哦,我刚才看到这不是你的问题 :-) - Smittii

0

我有同样的问题。我正在使用CMAKE,问题是我没有将globals.cpp文件放入CMAKE可执行文件中。这个问题应该类似,实现本身没有问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接