2016-10-07 81 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"; 
} 
主文件

相關問題