2011-04-14 31 views
1

我知道这将有一个简单的答案,但难倒。我已经尽可能简化了代码,以实现这一点。静态字符数组在行间意外行为

我有一个简单的头文件,称它为啊

它具有以下,仅此而已(它作为一个全球性的设置文件在我的项目,选择包含的所有文件)

#ifndef A_H 
#define A_H 
namespace settings{ 
    static char name[16]={'\0'}; 
} 
#endif 

我再有另一个类,有自己的头文件,让我们把它叫做b.cpp(BH与未显示)

#include "a.h" 

void B::doSomething() 
{ 
    strcpy(settings::name,"I like Dogs"); 
} 

最后,该访问设置::名第三类,它命名为c .cpp(与c.h没有显示)

#include "a.h" 

void C::printSomething() 
{ 
    printf("Some Girls Say %s\n",settings::name); 
} 

唉,所有打印的是“有些女孩说”。是什么赋予了?我不明白如何设置::名称是不存在的功能破坏B :: doSomething()(我只能猜测这是问题)。是strcpy懒惰,只是指向设置::名称到“我喜欢狗”开始,而不是实际上像strdup行事?

任何帮助和解决方法非常感谢。谢谢!

编辑:为了进一步明确,C.doSomething()在C.printSomething()之前被调用。

+0

这里没有足够的信息。我们需要知道包含的顺序和代码中的控制流。根据一般经验,不要在头文件中声明** static **变量。 – Chintan 2011-04-14 20:15:39

回答

7

static关键字将name链接到它所包含的每个翻译单元中,因此每个.cpp文件基本上都有其自己的版本name

你想要做的就是把什么name你想在一个.cpp文件(共享没有static并在.h文件extern联动声明它

所以这就是:

一的.cpp

namespace settings { 
    char name[16] = { 0 }; 
} 

namespace settings { 
    extern char name[16]; 
} 

b.cpp

void B::doSomething() 
{ 
    strcpy(settings::name,"I like Dogs"); 
} 

c.cpp

#include "a.h" 

void C::printSomething() 
{ 
    printf("Some Girls Say %s\n",settings::name); 
} 
+0

谢谢罗纳德,这工作。我涉猎了一段时间,但并不知道它需要首先在a.cpp中初始化(即你的例子)。我反过来在b.cpp中初始化它,并且visual studio抱怨说不允许将它设置在当前范围内......不知道该交易是什么,但无论如何,它更直观。谢谢。 – jparanich 2011-04-14 20:22:39

1

通过在两个源文件头,你有两个独立的存储位置。包含头文件有点像将代码粘贴到源文件中。所以他们每个人都有他们自己的名为'name'的静态变量。

为了得到这个做你想要什么,你需要:

  • 使用的extern,不是一成不变的,在头中。这实际上意味着每个包含头文件的文件都会引用一个变量外部的变量。
  • 在其中一个源文件中定义该变量。它需要在某个地方定义一次。定义时不要使用静态或外部。
+0

感谢您的解释卢克! – jparanich 2011-04-14 20:26:24

0

首先在a.cpp

namespace settings{ 
    char name[16]; 
} 

写那么确保

B::doSomething() 

被调用。