没有适当的默认构造函数可用初始化ostream指针

时间:2014-11-17 17:16:12

标签: c++ iostream

我正在尝试创建一个这样的日志类:

#include <iostream>
#include <fstream>

class logstream : public std::ostream
{
public:
  logstream() : os(&std::cout), file_(false) {}  // line 7

  logstream(const char* filename) : os(new std::ofstream("file.txt")), file_(true) {
    // open file - raise exception if cannot open

  }

  ~logstream() {
     // check if file and if so close
    if(file_) {
      os->close();
      delete os;
    }      
  }

private:
  std::ostream* os;
  bool file_;
};

但是我在第7行得到了这个错误:

error C2512: 'std::basic_ostream<_Elem,_Traits>' : no appropriate default constructor available
1>        with
1>        [
1>            _Elem=char,
1>            _Traits=std::char_traits<char>
1>        ]

同样的错误在第9行:

error C2512: 'std::basic_ostream<_Elem,_Traits>' : no appropriate default constructor available
1>        with
1>        [
1>            _Elem=char,
1>            _Traits=std::char_traits<char>
1>        ]

我还需要在os-&gt;关闭行上修复此错误:

error C2039: 'close' : is not a member of 'std::basic_ostream<_Elem,_Traits>'
1>        with
1>        [
1>            _Elem=char,
1>            _Traits=std::char_traits<char>
1>        ]

如何修复这些编译错误?

更新

所以我可以这样做:

class logstream 
{
public:
  logstream() : os(&std::cout), file_(false) {}

  logstream(const char* filename) : os(new std::ofstream("file.txt")), file_(true) {
    // open file - raise exception if cannot open

  }

  ~logstream() {
     // check if file and if so close
    if(file_) {
      static_cast<std::ofstream*>(os)->close();
      delete os;
    }      
  }

private:
  std::ostream* os;
  bool file_;
};

使用内部ostream对象。或者我可以从ostream继承并删除内部ostream ptr。但是,如何为继承版本编写构造函数?

我在这个版本上遇到错误:

class logstream2 : public std::ostream
{
public:
  logstream2() : std::ostream(std::cout) {}

  logstream2(const char* filename) : std::ostream(std::ofstream("file.txt")) {
    // open file - raise exception if cannot open - check state of stream

  }

  ~logstream2() {
    // not sure if I need this     
  }
};

错误:

error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>'
1>        with
1>        [
1>            _Elem=char,
1>            _Traits=std::char_traits<char>
1>        ]
1>        c:\program files (x86)\microsoft visual studio 9.0\vc\include\ios(151) : see declaration of 'std::basic_ios<_Elem,_Traits>::basic_ios'
1>        with
1>        [
1>            _Elem=char,
1>            _Traits=std::char_traits<char>
1>        ]
1>        This diagnostic occurred in the compiler generated function 'std::basic_ostream<_Elem,_Traits>::basic_ostream(const std::basic_ostream<_Elem,_Traits> &)'
1>        with
1>        [
1>            _Elem=char,
1>            _Traits=std::char_traits<char>
1>        ]

这就是我最终的目标。

#include <iostream>
#include <fstream>

class logstream
{
public:
  logstream() : os(&std::cout), file_(false) {}

  logstream(const char* filename) : os(new std::ofstream(filename)), file_(true) {
    // open file - raise exception if cannot open - TODO
  }

  ~logstream() {
     // check if file and if so close
    if(file_) {
      static_cast<std::ofstream*>(os)->close();
      delete os;
    }      
  }

  template<typename T>
  std::ostream& operator<<(const T& o) {
    return *os << o;
  }

private:
  std::ostream* os;
  bool file_;
};


int main () {
  logstream log("logtest.txt");
  log << "Hi Guys!\n";
  log << "number: " << 3 << std::endl;
  return 0;
}

2 个答案:

答案 0 :(得分:2)

您需要在初始化列表中调用从您继承的类std::ostream的构造函数。

答案 1 :(得分:2)

这个怎么样?

#include <iostream>
#include <ostream>
#include <fstream>
#include <string>
#include <memory>

class logstream
{
public:
    logstream() : os(new std::ostream(std::cout.rdbuf())), file_(false) {}  // line 7

    logstream(const std::string &filename) :
        os(new std::ofstream(filename)), file_(true)
    {
        // open file - raise exception if cannot open

    }

    std::ostream &operator<<(const std::string &s)
    {
        *os << s;
    }

    ~logstream()
    {
        // check if file and if so close
        if (file_)
        {
            dynamic_cast<std::ofstream*>(os.get())->close();
        }
    }

private:
    std::unique_ptr<std::ostream> os;
    bool file_;
};

int main()
{
    logstream l("test.txt");
    l << "some test"; // write to test.txt

    logstream another;
    another << "another test"; //write to std::cout by default
}