2016-10-07 52 views
5

我的代码非常大,但我会尽可能地尽量减少它。为什么全局定义的静态变量被重置?

基本上我想定义一个字符串,只修改一个地方(我的主),然后在我的整个程序中读取。

我的defines.h包含在任何地方,所以在那里我定义。

static std::string MAINLOG = "RANDOMNES"; 

在我的主要功能我做的:

for (int i = 0; i < files.size(); i++){ 

    // Do stuff  

    prepDbugDir(); // This sets MAINLOG to "CORRECT_VALUE" 

    std::cout << "Before " << MAINLOG << std::endl; 

    // Call a class function whose includes include my defines.h 

    std::cout << "After " << MAINLOG << std::endl; 


} 

和打印出我的文件是

Before CORRECT_VALUE 
RANDOMNESS 
After CORRECT_VALUE 

所以我的问题是为什么,我怎样才能获得值为保持在我的课堂内。

+0

您是否将您的程序信息分成几个* .a或* .o?看起来由于您将编程分割为多个目标文件,因此存在多个MAINLOG副本。 –

+0

编译时,是的。如果这是问题,有没有办法解决这个问题? – aarelovich

+1

尝试将MAINLOG的声明放入标题中,并且只在包含标题(可能为defines.cpp)的单个.cpp文件中定义一次。 – Baldrick

回答

6

包含defines.h的每个翻译单元(基本上是.c或.cpp文件)都将拥有自己的变量副本。

我相信,宣布在头

extern std::string MAINLOG; 

全球extern,然后将其定义为在.c和.cpp文件中的任何一个一个非静态全局变量

std::string MAINLOG = "RANDOMNES"; 

将解决问题。但这是糟糕的编码风格,海事组织。 C++方式至少是一个单例类。

我不能没有知道的情况下给出有意义的名字,但这个想法如下:

mainlog.h

class Mainlog { 
    Mainlog() = default; // Private default constructor 

    static Mainlog& instance(); 

public: 
    static const std::string& get() { 
     return instance().value; 
    } 

    static void set(const std::string& newValue) { 
     instance().value = newValue; 
    } 

private: 
    std::string value {"RANDOMNESS"}; 
}; 

mainlog.cpp(不要把这个头! )

Mainlog& Mainlog::instance() { 
     static Mainlog mainlog; 
     return mainlog; 
    } 
+1

中使用'extern std :: string MAINLOG'同意单例类比全局静态属性更好 –

+0

我有一个main.cpp,然后我的类正确。我在我的定义和我的main(在我的main.cpp中)声明了主日志是外部的,我将它设置为值。当我这样做时,我得到链接器错误:未定义的引用到'MAINLOG',我真的想读它。 – aarelovich

+1

你能举个单身课的例子吗? – aarelovich

3

这是我会推荐的。

在defines.h:

const std::string& mainlog(); 

在main.cpp中:

const std::string& mainlog() { 
    static std::string MAINLOG = "CORRECT_VALUE"; 
    return MAINLOG; 
} 
+0

不能使用const,因为在运行期间该值会多次更改。 – aarelovich

+0

但是你想要改变它。你不希望其他人能够改变它,所以他们看到一个const引用,但不能修改它。这也是第一个发布的单身人士。但是你也可以返回一个MAINLOG的副本(只是std :: string) –

1

因为你把它放在你的defines.h文件,然后您可以在您的.cpp文件,每个文件.cpp文件获取自己的字符串实例,仅在该.cpp文件中可见。 static只在声明了.cpp的地方生成一个变量。

改变静态为extern在defines.h,像这样:

extern std::string MAINLOG;

然后在一个只有你一个。cpp文件,添加:

std :: string MAINLOG =“RANDOMNES”;

这会给你你期望的行为,但像这样的全局变量是一个坏主意。

+0

你不希望头文件中的条目有初始值设定项。 –

+0

这是正确的。我会修好它。 (剪贴的喜悦) –

0

当您在标题中使用静态存储器定义变量时,每个翻译都将通过该名称获取自己的唯一变量。

一个简单的修复,如果你不想去的单方式,是在你的头部声明

extern const std::string& MAINLOG; 

,然后主文件定义

std::string MAINLOG_INTERNAL = "RANDOMNESS"; 
const std::string& MAINLOG = MAINLOG_INTERNAL; 

这会给你是一个可写的字符串,在程序的其余部分有一个只读的“视图”。

然后你可以

void prepDbugDir() 
{ 
    MAINLOG_INTERNAL = "CORRECTNESS"; 
} 
主文件

相关问题