C++ C++;-在我自己的课堂上使用ostream
我在logger类中使用ostream时遇到问题。由于某些原因,std::endl从未打印出来,因此没有添加换行符。我肯定是出了什么问题,我在试图理解如何在自己的课堂上使用我的ostream时遇到了问题,所以我可能做了一些根本性的错误C++ C++;-在我自己的课堂上使用ostream,c++,windows,io,C++,Windows,Io,我在logger类中使用ostream时遇到问题。由于某些原因,std::endl从未打印出来,因此没有添加换行符。我肯定是出了什么问题,我在试图理解如何在自己的课堂上使用我的ostream时遇到了问题,所以我可能做了一些根本性的错误 class MyStreamBuf : public std::streambuf { public: MyStreamBuf() : std::streambuf() { } }; class MyLogger : publ
class MyStreamBuf : public std::streambuf
{
public:
MyStreamBuf() : std::streambuf()
{
}
};
class MyLogger : public std::ostream
{
public:
MyLogger(MyStreamBuf* buf) : std::ostream(buf) { mBuf = buf; }
~MyLogger() { delete mBuf; }
template <typename T>
inline MyLogger& operator << (T const& value)
{
#ifdef _WIN32 || _WIN64
std::cout << value;
#endif
return *this;
}
inline std::ostream& operator << (std::ostream& (*f)(std::ostream&))
{
return f(*this);
}
MyStreamBuf* mBuf;
};
int _tmain(int argc, _TCHAR* argv[])
{
MyStreamBuf* buf = new MyStreamBuf();
MyLogger logger(buf);
logger << "kekekek" << "asdf: " << 23 << std::endl;
logger << "kekekek" << "asdf: " << 23 << std::endl;;
getchar();
return 0;
}
你需要把endl发送到某个地方。通过执行
f(*this)
您试图将其发送给您自己,但您的对象没有必要的方法来执行此操作。如果查看#include
,函数endl
使用函数put
将\n
放入流中,然后刷新它
你需要把结尾写在某个地方。例如,如果您正在向cout
写信,那么您可以这样做
(*f)(std::cout);
你需要把endl发送到某个地方。通过执行
f(*this)
您试图将其发送给您自己,但您的对象没有必要的方法来执行此操作。如果查看#include
,函数endl
使用函数put
将\n
放入流中,然后刷新它
你需要把结尾写在某个地方。例如,如果您正在向cout
写信,那么您可以这样做
(*f)(std::cout);
试试这个:
inline std::ostream& operator << (std::ostream& (*f)(std::ostream&))
{
std::cout << f;
return *this;
}
inline std::ostream&operator尝试以下操作:
inline std::ostream& operator << (std::ostream& (*f)(std::ostream&))
{
std::cout << f;
return *this;
}
inline std::ostream&operator使用自定义流缓冲区类时,基本方法是正确的。但是,这是您想要实现特定逻辑的地方,而不是在从std::ostream
派生的类中
仅解释一下当前发生的情况:当您调用f(*this)
函数f()
时,将使用std::ostream
基调用函数f()
,它接收输出并调用flush()。你的课完全不可能
以下是您应该做的:
*从MyLogger
类中删除输出运算符
*在流缓冲区中实现overflow()
,以处理缓冲区溢出的问题(例如,在某处发送字符或增加缓冲区)
*实现sync()
以发送任何缓冲字符,并在刷新流时执行任何其他需要执行的操作
*可能MyLogger
应该拥有流缓冲区并正确设置其花瓶;通常,这些都是从std::ostream
派生的类所做的
这里有很多关于这一点的例子。搜索streambuf
和James Kanze或me来找到一对夫妇。使用自定义流缓冲区类时,基本方法是正确的。但是,这是您想要实现特定逻辑的地方,而不是在从std::ostream
派生的类中
仅解释一下当前发生的情况:当您调用f(*this)
函数f()
时,将使用std::ostream
基调用函数f()
,它接收输出并调用flush()。你的课完全不可能
以下是您应该做的:
*从MyLogger
类中删除输出运算符
*在流缓冲区中实现overflow()
,以处理缓冲区溢出的问题(例如,在某处发送字符或增加缓冲区)
*实现sync()
以发送任何缓冲字符,并在刷新流时执行任何其他需要执行的操作
*可能MyLogger
应该拥有流缓冲区并正确设置其花瓶;通常,这些都是从std::ostream
派生的类所做的
这里有很多关于这一点的例子。搜索streambuf
和James Kanze或我来找到一对夫妇。endl
不是常数或类似的东西。相反,它是一个函数,就像std::endl(std::cout)
。您可以为此做出具体安排。为什么不实施std::streambuf
?通过这种方式,您可以执行如下操作:MyStreamBuf*buf=newmystreambuf();std::ostream记录器(buf)
您应该只实现3个功能:同步
、溢出
和下溢
。您可以将所有内容打印到cout
,而不是endl
!(第一个重载是为值触发的,最后一个重载是为endl
触发的,第一个重载包含coutendl
不是常数或类似的东西。相反,它是一个函数,如std::endl(std::cout)
。您可能会为此做出具体安排。为什么不实施std::streambuf
呢?这样,您可以执行如下操作:MyStreamBuf*buf=new MyStreamBuf();std::ostream logger(buf)
您应该只实现3个功能:sync
、overflow
和underflow
。您可以将所有内容打印到cout
,但不能打印到endl
!(首先为值触发重载,最后为endl
并首先包含cout