我正在尝试创建一个这样的日志类:
#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;
}
答案 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
}