如何在C ++中构造静态全局变量

时间:2009-07-13 21:47:13

标签: c++ global-variables

我在编译/链接一组类时遇到一些麻烦,其中一些类处理一个公共的全局变量。

基本上,我在A类中声明并定义了一个extern变量foo,并在B和C类中访问/更新它。

相关代码如下所示:

A.h

extern string foo; // declare it <=== compiler error "storage class specified for foo"

B.cpp

include A.h  
string foo; // define it  

main () {   
...  
foo = "abc";      
}  

C.cpp

include A.h  
cout << foo; // print it  

我当前的错误是“为foo指定的存储类”。但是,我想知道这是否是正确的方法。我应该使用静态变量吗?任何帮助都非常感激,因为我已经在这至少一个小时了。

8 个答案:

答案 0 :(得分:5)

由于您的错误出现在extern上,我猜它不知道类型是什么。

你收到了字符串吗?

#include <string>

如果是这样,您需要在其前面放置std::

#include <string>
extern std::string foo;

附注,请确保您的头文件中没有使用任何using指令(using namespace stdusing std::string),因为这会强制所有起诉您的头文件的人做同样,这是不好的做法。

修改

  

......但这就是我编码的方式。

你确定吗?我刚试过这个,它在VC ++和g ++中都运行得很好:

A.H

#include <string>

extern std::string foo;

B.cpp

#include "A.h"

std::string foo;

int main (void)
{   
    foo = "abc";      
}

C.cpp

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

int some_function(void)
{   
    std::cout << foo << std::endl;
}

尝试一下,看看它是否有效。

答案 1 :(得分:4)

在文件级别执行此操作。在main()外面

string foo;

int main(){

}

否则它根本不是全球性的,而是“自动”

答案 2 :(得分:2)

虽然EFraim的答案是正确的,但另一个问题是,这是否是正确的方法。答:不,在大多数情况下。

拥有一个由多个类操纵的单一全局值只是乞求问题:使用 extern 非常微妙。任何程序员都没有明确的提示来查看定义变量的代码。他/她必须进行完整的源扫描才能找到它。此外,很难确定何时类更改应用程序控制流中的值,全局变量将不同的类与不可见的带绑定在一起。一个好的设计使类之间的协作变得明确。

更好:让您的全局变为singleton。这样,您至少可以知道值的定义位置,并且可以通过访问方法控制对值的更改。 更好的是:弄清楚为什么类必须能够访问相同的值,找出哪个类完全依赖于哪个方面并相应地修改你的设计。使用 extern 通常足以解决更深层次的设计问题。

答案 3 :(得分:2)

在A.h你真的在实际的A班中得到了extern声明吗?你的问题目前用文字说明,但是你的代码片段表明它是在文件级别。我可以解决你所讨论的错误的唯一方法,即“为foo指定的存储类”,这是A.h中的以下内容:

class A
{
public:
    extern std::string foo;
};

也许这是你的问题?

编辑:看看你自己的答案,我认为这就是你所做的。您想要将extern替换为static,然后使用类似

的行在A.cpp中定义该静态
std::string A::foo;

然后,您可以随后在A::foo等其他地方访问它,例如

std::cout << A::foo;

答案 4 :(得分:1)

除了将定义移到main之外,请确保在extern声明之前包含字符串标题:

#include <string>

答案 5 :(得分:1)

好吧,看起来C ++不允许你在除了对象或函数之外的任何东西上使用“extern”:

来自http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=/com.ibm.xlcpp8a.doc/language/ref/extsc.htm

“C ++将extern存储类说明符的使用限制为对象或函数的名称。使用带有类型声明的extern说明符是非法的。外部声明不能出现在类范围中。”

回到绘图板......

答案 6 :(得分:1)

GMan的答案是正确的:如果不包含字符串,则会尝试实例化未定义的类型,从而导致错误。

标准中引用的东西不合适:Jack并没有尝试将类型定义为静态,他试图实例化一个对象。

是的,你只能做像

这样的事情
class foo {
  // ...
  static int hoo; // class variable same in all instances of foo
  // ...
};

......但这不是杰克正在做的事情。

为什么我的所有代码都会在此BBS中被破坏?上周提出了一个关于C指针的答案,当我想要单个时,我最后得到了双星号!

答案 7 :(得分:0)

在定义foo时,您在函数main中定义了一个局部变量。当你链接时,你会得到一个丢失的符号,因为你的外部foo;永远不会创造。你需要在函数外定义foo。

b.cpp

string foo;
int main () {
   foo = "abc";
}

更好的是,你应该尝试单身。