cout 과 ofstream 으로 동시 출력해주는 stream 을 정의하려면?

jinserk의 이미지

안녕하세요..
A, B, C, ... 등등을 출력스트림으로 뽑아야 하는데, 파일과 화면에 둘다 보여지게 하고 싶습니다.
기왕하는거 좀더 OO 적으로 해보고 싶어서 logstream 을 하나 만들고 싶은데요.
화면에 찍거나 파일에 찍거나 하는걸 선택할 수 있도록요.

처음엔 ofstream 을 상속해서 만들어 보려고 했더니 엄청난 에러가 쏟아지네요.
검색을 해보니 ostream 을 상속받지 말라는 말도 보이구요.

그래서 ofstream 객체를 포함하는 log 클래스를 정의하고 operator<< 를 정의해주는 식으로 갔는데,
이렇게 하면 logfs << A << B 와 같은 모양으로 쓸수는 있지만
print(ostream& os) 와 같은 형태의 함수에 인자로 넣을 수가 없습니다.

ostream 속성을 가지면서 cout 과 ofstream 으로 동시 출력하는 클래스를 어떻게 만드는게 정석인가요?
감사합니다.

익명 사용자의 이미지

오래 되서 잘 기억은 안나지만 streambuf 계층에서 처리해주는 게 정석이었던 것 같군요.

jinserk의 이미지

감사합니다.
그런데, 어차피 streambuf를 상속해서 logstreambuf 를 정의하고 이걸 포함하는 ostream 상속 객체를 만든다고 해도, 내부 streambuf 가 하나밖에 없을 텐데, cout 과 filebuf 를 동시에 건드려줄 수 있나요?
제가 잘 이해를 못하는 건지..

Leo.

익명 사용자의 이미지

   5 #ifndef __LOGSTREAM_H__
   6 #define __LOGSTREAM_H__
   7 
   8 #include <streambuf>
   9 #include <fstream>
  10 
  11 namespace mylib {
  12 
  13     class logstreambuf : public std::streambuf
  14     {
  15         typedef std::char_traits<char>  traits_type;
  16         typedef traits_type::int_type   int_type;
  17 
  18         private:
  19             std::streambuf* sb1_;
  20             std::streambuf* sb2_;
  21             bool            sb2_en_;
  22 
  23         public:
  24             logstreambuf() : sb1_(NULL), sb2_(NULL) {}
  25             logstreambuf(std::streambuf* sb1, std::streambuf* sb2)
  26                 : sb1_(sb1), sb2_(sb2) {} 
  27                 
  28             void init(std::streambuf* sb1, std::streambuf* sb2)
  29             {
  30                 sb1_ = sb1;
  31                 sb2_ = sb2;
  32             }   
  33             
  34         protected:
  35             int_type overflow(int_type c)
  38             { 
  39                 if (!traits_type::eq_int_type(c, traits_type::eof())) {
  40                     c = sb1_->sputc(c); 
  41                     if (!traits_type::eq_int_type(c, traits_type::eof()))
  42                         c = sb2_->overflow(c); 
  43                     return c; 
  44                 }   
  45                 else
  46                     return traits_type::not_eof(c);
  47             }       
  48             
  49             int sync()
  50             { 
  49                 int rc = sb1_->sync();
  50                 if (rc != -1)
  51                     rc = sb2_->sync();
  52                 return rc;
  53             }
  54 
  55     }; // class logstreambuf
  56 
  57     class logstream : public std::ostream
  58     {
  59         private:
  60             std::ofstream   ofs_;
  61             logstreambuf    buf_;
  62 
  63         public:
  64             logstream() : std::ios(0), std::ostream(&buf_) {}
  65             logstream(char* filename) : std::ios(0), std::ostream(&buf_)
  66             {
  67                 buf_.init(ofs_.rdbuf(), std::cout.rdbuf());
  68                 open(filename);
  69             }
  70 
  71             void open(char* filename)
  72             {
  73                 ofs_.open(filename);
  74             }
  75 
  76     }; // class logstream
  77
  78 }; // namespace mylib
  79 

여기까진 만들었는데.. 막상 아래와 같은 에러가 나네요.

/usr/include/c++/4.2.1/streambuf: In member function ‘virtual int mylib::logstreambuf::overflow(int)’:
/usr/include/c++/4.2.1/streambuf:763: error: ‘typename _Traits::int_type std::basic_streambuf<_CharT, _Traits>::overflow(typename _Traits::int_type) [with _CharT = char, _Traits = std::char_traits<char>]’ is protected
../src/logstream.h:40: error: within this context
/usr/include/c++/4.2.1/streambuf: In member function ‘virtual int mylib::logstreambuf::sync()’:
/usr/include/c++/4.2.1/streambuf:623: error: ‘int std::basic_streambuf<_CharT, _Traits>::sync() [with _CharT = char, _Traits = std::char_traits<char>]’ is protected
../src/logstream.h:49: error: within this context
/usr/include/c++/4.2.1/streambuf:623: error: ‘int std::basic_streambuf<_CharT, _Traits>::sync() [with _CharT = char, _Traits = std::char_traits<char>]’ is protected
../src/logstream.h:51: error: within this context
../src/main.cpp: In function ‘int main(int, char**, char**)’:
../src/main.cpp:12: warning: deprecated conversion from string constant to ‘char*’
make: *** [../src/main.o] Error 1

뭐.. streambuf 의 멤버함수 overflow 와 sync 가 protected 이니 당연하긴 한데..
대체 streambuf 안에 두개의 서로 다른 sreambuf 를 어떻게 넣어야 하는건지 전혀 감을 못잡겠습니다. :(
조언 부탁드립니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.