2012-04-21 20 views
2

私は、多くのファイル操作でC++でプログラムを開発しています。私は共通のヘッダーにstatic ofstreamを定義して、プロジェクトのどこにでもアクセスできるようにしました。コードの構造は以下の通りです:共通変数はすべてcom.hで定義されています。test.hとtest.cppはOPClassというクラスです。main.cppはメインプログラムを運びます。static 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 

実際にあなたの宣言を置く場所はあなた次第ですが、それが1か所にあることを確認してください。それはcom.cppファイルでもかまいません。もしそれがあなたのプロジェクトに合っていれば、main.cppに貼り付けることもできます。

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

このように、グローバル変数は、とにかく...

+0

ありがとうございます。できます。私はちょうど1つの質問を持っています、なぜヘッダーに "using"ステートメントを入れてはいけないのですか?とにかく、代わりに実装(つまりcpp)に入れることができますか?ありがとう – user1285419

+2

よろしくお願いします。 'using'は実装ファイルでは問題ありませんが、ヘッダーでは悪い習慣とみなされています...なぜそれが当てはまるのかについてのQ&Aです:http://stackoverflow.com/questions/2232496/is-it-wrong-to-use- c-using-a-header-file – HostileFork

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ディスプレイ2つの異なるアドレスのための2つのprint文ということに気づくでしょう。これは、2つの異なる変数として実際に2つのインスタンスoutが作成されていることを示します。 OPClassのメソッドが完全に異なる出力ストリームに書き込もうとしています。これは、グローバルコンテキストでstaticを使用している方法と関係があります。それはあなたが思っているように振る舞いません。グローバルコンテキストでは、staticと宣言すると、それをそのファイルのローカルスコープにバインドします。

関連する問題