2012-04-21 36 views
2

我在C開發程序++有很多文件IO操作。我在一個共同的頭文件中定義了一個靜態的流,以便在項目中的任何地方都可以訪問它。碼的結構如下面的列表:所有公共變量在com.h,test.h和TEST.CPP定義是一個名爲的opclass類,main.cpp中攜帶主程序爲什麼靜態的ofstream不起作用

COM.H:

#ifndef __CLCOM__ 
#define __CLCOM__ 
#include <sstream> 
#include <fstream> 
#include <iostream> 

using namespace std; 

static ofstream out; 
static stringstream ss; 

#endif 

TEST.H:

#ifndef __CL__ 
#define __CL__ 
#include <iostream> 
#include <fstream> 
#include "com.h" 

using namespace std; 

class OPClass 
{ 
    public: 
    void run(void); 
    void show(ostream &o) const; 
}; 
#endif 

TEST.CPP:

#include "com.h" 
#include "test.h" 

void OPClass::run(void) 
{ 
    out << "Here is run()" << endl; 
    show(out); 
} 

void OPClass::show(ostream &o) const 
{ 
    o << "hello!" << endl; 
} 

main.cpp中:

#include "com.h" 
#include "test.h" 

void runmain(void) 
{ 
    OPClass op; 
    out.open("output.txt", ios::out | ios::trunc); 
    out << endl << "State changed!" << endl; 
    op.run(); 
    if (out.is_open()) out.close(); 
} 

int main(int argc, char* argv[]) 
{ 
    runmain(); 
    return 0; 
} 

正如你所看到的,靜態的ofstream被命名爲出,將在主程序和在類中調用。我使用的是mingw32,在編譯或運行時沒有看到任何問題。但似乎只有runmain()中的信息將被寫入輸出文件。寫入該文件的任何其他消息都不會出現在輸出文件中。爲什麼這麼做,我該如何編寫一個公共文件流,以便項目中的任何地方都可以訪問它?謝謝。

回答

2

每個編譯單元取得自己ssout。因此,main.cpp看到的不同實例與test.cpp有所不同。

你並不真的需要靜態這裏。爲了解決這個問題,而不是聲明變量及其分配在頭文件,你需要使用extern關鍵字只是原型他們。

#ifndef __CLCOM__ 
#define __CLCOM__ 
#include <sstream> 
#include <fstream> 
#include <iostream> 

// Note: don't put "using" statements in headers 
// use fully qualified names instead 
extern std::ofstream out; 
extern std::stringstream ss; 

#endif 

如果你實際上把你的聲明是你的,只是確保它是隻在一個地方。這可能是一個com.cpp文件,或者您可以將其保存在main.cpp中,如果這適合您的項目。

std::ofstream out; 
std::stringstream ss; 

不喜歡這個全局變量是一個好主意,反正...

+0

非常感謝。有用。我只有一個問題,爲什麼我們不應該在頭文件中使用「使用」語句?無論如何,我可以把它放在執行(即cpp)嗎?謝謝 – user1285419 2012-04-21 06:08:06

+2

歡迎。在實現文件中使用''是好的,但是在頭文件中被認爲是一個不好的做法......這是關於爲什麼是這種情況的Q&A:http://stackoverflow.com/questions/2232496/is-it-wrong-to-use- C-使用關鍵字 - 在-A-頭文件 – HostileFork 2012-04-21 06:10:41

1

搶先發言:你應該接受@ HostileFork的答案。

正如增編,一個簡單的方法來顯示所發生的事情是打印出的out地址,只要你嘗試使用它。

如果添加這些夫婦聲明:

void OPClass::run(void) 
{ 
    cout << "Address of 'out' = " << &out << endl; 
    out << "Here is run()" << endl; 
    show(out); 
} 

和:

void runmain(void) 
{ 
    cout << "Address of 'out' = " << &out << endl; 
    OPClass op; 
    out.open("output.txt", ios::out | ios::trunc); 
    out << endl << "State changed!" << endl; 
    op.run(); 
    if (out.is_open()) out.close(); 
} 

你會發現,爲out顯示兩個不同的地址的兩個打印語句。這應該告訴你,你實際上得到兩個不同的變量產生的out兩個實例。 OPClass中的方法試圖寫入完全不同的輸出流。它與您在全球範圍內使用static的方式有關;它不像你想象的那樣行事。在全局範圍內,聲明static將其綁定到它所在文件的本地範圍。