C++ 如何在C++;

C++ 如何在C++;,c++,global-variables,C++,Global Variables,我在编译/链接一组类时遇到了一些问题,其中几个类处理一个公共全局变量 基本上,我在类a中声明和定义一个外部变量foo,并在类B和C中访问/更新它 相关代码如下所示: A.h extern string foo; // declare it <=== compiler error "storage class specified for foo" C.cpp include A.h cout << foo; // print it 包括A.h 不能在文件级执行。外干管

我在编译/链接一组类时遇到了一些问题,其中几个类处理一个公共全局变量

基本上,我在类a中声明和定义一个外部变量foo,并在类B和C中访问/更新它

相关代码如下所示:

A.h

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

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

不能在文件级执行。外干管()

串福

int main(){

}


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

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

b、 cpp


更好的是,您应该尝试使用单例。

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

#include <string>
#包括

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

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

更好:让你的全球成为一个好朋友。这样,您至少知道值的定义位置,并且可以通过访问方法控制对值的更改。
更好的是:找出为什么类必须访问相同的值,找出哪个类取决于具体的方面,并相应地修改您的设计。经常使用extern只是一个更深层设计问题的快速解决方案。

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

你把绳子包括进去了吗

#包括

如果是这样,您需要在它前面加上
std::

#include <string>
extern std::string foo;
B.cpp C.cpp
#包括“A.h”
#包括
int一些函数(void)
{   

STD::CUT

,TT看起来像C++,除了对象或函数之外,不允许你使用“外部”:

“C++将外部存储类说明符的使用限制为对象或函数的名称。将外部说明符与类型声明一起使用是非法的。外部声明不能出现在类作用域中。”


回到绘图板…

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

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

是的,你只能做这样的事情

class foo {
  // ...
  static int hoo; // class variable same in all instances of foo
  // ...
};
……但杰克不是这么做的


为什么我所有的代码都在这个BBS上被弄乱了?上周我给出了一个关于C指针的答案,当我想要单指针的时候,我得到了双asterix!在A.h中,你真的在实际的类A中得到了extern声明了吗?你的问题目前是用文字表达的,但是你的代码片段表明它是在文件级的我可以通过一种方式得到您所说的错误,即“为foo指定的存储类”用于A.h中的以下内容:

class A
{
public:
    extern std::string foo;
};
也许这就是你的问题

编辑:看看你自己的答案,我想这就是你所做的。你想用
static
替换
extern
,然后在A.cpp中用一行

std::string A::foo;
随后,您可以在其他地方访问它,如
A::foo
eg

std::cout << A::foo;

std::cout谢谢,但运气不好。它仍然在外部声明中给我“为foo指定的存储类”消息。不要包含“A.h”在B.cpp中。只在C.cpp中包含它。实际上,您不应该将外部声明放入头文件中。最好将外部字符串foo;放在正在使用它的cpp文件的顶部。而且更好的是:不要使用外部字符串。;)有关详细信息,请参阅我的答案。@haffax:我不完全同意。有一堆常量字符串(或任何其他非平凡对象)共享是一件显而易见的事情。在这种情况下,你会有一个标题列出它们,每个标题上都有“extern”,还有一个源文件和实际的定义。在这种情况下,使用单例将是巨大的过度使用。即使一个单例包含全部内容,也会使访问它们变得毫无意义的冗长。对于非常量变量les尽管我同意应该按照你的建议以更简洁的方式处理它。@Troubador,最初的问题明确地说foo由B和C访问/更新。即使它是一个常量字符串,我也会让编译器处理常量方面(它将统一常量字符串)或者,我会使B和C对字符串的依赖关系显式化。Singleton只是一个例子。有很多方法可以解决这个问题。字符串可以作为ctor或init方法的参数提供。或者字符串可以是B和C的某个常见依赖关系的属性。两者都比使用外部引用全局对象更可取从面向对象的角度来看这个问题。@haffax:你关于不在标题中添加外部声明的评论显然是作为一般性建议提供的。因此,这就是我在我的评论中对它的回应。Jim-我在B.cpp中包含外部声明。B.cpp包含有外部声明的a.h。确认,markdown遗漏了一些文本。我的意思是我不想在你的extern之前包含STL字符串头。遗憾的是,我认为他抛弃了他的问题。不幸的是,因为我认为我们是对的。事实上,综观他自己的答案,我认为他试图“extern”类中的某个东西(比如静态成员),尽管它不是
#include "A.h"
#include <iostream>

int some_function(void)
{   
    std::cout << foo << std::endl;
}
class foo {
  // ...
  static int hoo; // class variable same in all instances of foo
  // ...
};
class A
{
public:
    extern std::string foo;
};
std::string A::foo;
std::cout << A::foo;