为什么静态ofstream不起作用

时间:2012-04-21 04:00:11

标签: c++ ofstream

我正在开发一个带有大量文件io操作的c ++程序。我在一个公共头中定义了一个静态流,以便在项目的任何地方都可以访问它。代码的结构列表如下:所有公共变量都在com.h中定义,test.h和test.cpp用于一个名为OPClass的类,main.cpp带有主程序

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;
}

如您所见,static ofstream被命名为out,将在主程序和类中调用。我正在使用mingw32并没有看到编译或运行时出现任何问题。但似乎只有runmain()中的信息才会写入输出文件。写入该类文件的任何其他消息都不会出现在输出文件中。为什么这样,我怎样才能编写一个公共文件流,以便项目中的每个地方都可以访问它?感谢。

2 个答案:

答案 0 :(得分: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;

不管怎样这样的全局变量都不是一个好主意......

答案 1 :(得分: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会将其绑定到它所在文件的本地范围。