2012-04-21 41 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将其绑定到它所在文件的本地范围。