2012-04-21 2 views
2

나는 많은 파일 io 조작으로 C++로 프로그램을 개발 중입니다. 공통 헤더에 static ofstream을 정의하여 프로젝트의 모든 곳에서 액세스 할 수 있도록했습니다. 코드의 구조는 다음과 같습니다. 모든 공통 변수는 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 : 당신이 볼 수 있듯이, 정적 ofstream가 아웃로 명명 된 메인 프로그램 및 클래스에서 호출됩니다

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

. 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

감사합니다. 그것은 작동합니다. 나는 단지 하나의 질문을 가지고 있는데 왜 헤더에 "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 디스플레이 두 개의 서로 다른 주소에 대해 두 개의 잉크 문. 이것은 사실 두 개의 별개 변수로 생성 된 out의 두 인스턴스를 실제로 얻는다는 것을 알려줍니다. OPClass의 메소드가 완전히 다른 출력 스트림에 쓰려고합니다.글로벌 컨텍스트에서 static을 사용하는 방식과 관련이 있습니다. 그것은 당신이 생각하는 것처럼 행동하지 않습니다. 전역 컨텍스트에서는 무언가를 static으로 선언하면 해당 파일의 로컬 범위에 바인딩됩니다.

관련 문제