2012-04-30 96 views
1

我需要在多個源文件中使用static fstream。但是我只能從一個文件中使用它,而不能從其他文件中使用它。此外,它在其他文件中的使用不會給出任何錯誤,它只是無所作爲。我只能從一個文件訪問靜態fstream

這是代碼:

/// log.h 
#ifndef LOG_H 
#define LOG_H 
#include <fstream> 
static std::ofstream ofs; 
#define LOG(level) ofs << level << ": " 
#endif 

/// test.cpp 
#include "log.h" 
#include "other.h" 
int main() 
{ 
    ofs.open("file.log"); 
    LOG(5) << "Test log 1" << std::endl;  // OK 
    OtherFunc(); 
} 

/// other.h 
#ifndef OTHER_H 
#define OTHER_H 
extern int OtherFunc(); 
#endif 

/// other.cpp 
#include "other.h" 
#include "log.h" 
int OtherFunc() 
{ 
    LOG(5) << "Test log 2" << std::endl;  // Nothing 
} 

這是生成的文件:

5: Test log 1 

謝謝!

平臺:
Linux的
G ++ 4.5.1

+1

你應該考慮讓'LOG()'成爲一個普通的舊函數。將所需狀態(本例中的流)保留在函數實現的私有位置。這樣,您可以避免讓每個使用它的人都必須知道流。 –

回答

3

static這裏意味着你明確要求編譯器爲文件範圍的變量std::ofstream ofs靜態鏈接,這意味着它是唯一明顯在當前文件中。

的轉折是,你在一個頭,這意味着每.cpp文件包括頭獲取的std::ofstream ofs了自己鮮明的實例這樣做。僅僅因爲你給了它靜態鏈接,它們都可以有不同的文件範圍變量,並且具有相同的名稱 - 否則會出現名稱衝突。

因此,在main.cpp中,您打開本地並寫入它。 在other.cpp中,您有自己的本地副本,但從不打開它......所以輸出不會去任何地方,當然也不會去file.log


其他的答案是正確的,那改變了頭部聲明extern std::ofstream ofs;將允許所有.cpp文件共享稱爲一個對象,然後你只需要把該實例中只有一個地方(main.cpp會沒事的)。

儘管可以使LOG(level)作爲一個外聯函數調用,但它可能會更簡單,更乾淨;那麼輸出流可以在帶有函數定義的log.cpp中生存,並且沒有其他人需要來查看它。

+0

關於你最後的評論,你是正確的使用一個.cpp文件的記錄器實現,但我是一個特殊的情況下,我必須把所有內容放入一個包含文件。 – Pietro

+0

@Pietro:如果一切都在包含文件中,那麼'ofs'的單個實例在哪裏? –

3

我需要在多個源文件使用static fstream

如果您需要從多個源文件引用同一個變量,不是static聯動,即extern聯動。

在你的頭將這個:

std::ofstream ofs; 
+0

你說得對。我爲OtherFunc()做了它,並且我忘記了fstream。謝謝! – Pietro

4

靜態全局變量:聲明的變量爲靜態的源文件的頂層

extern std::ofstream ofs; 

在你的CPP文件正是一個將這個(在任何函數定義之外)僅在整個文件中可見(「文件範圍」,也稱爲「內部鏈接」)。 全局變量的默認存儲類別爲extern,它具有外部或整個程序鏈接。所以,如果你想使用在多個文件中的全局變量必須是extern.