我创建了自己的std::cout
- 类似对象,它将std::cout
写入日志文件。
我目前在头文件中这样定义它,但我收到了未使用的变量警告。
标头文件<MyLib/Log.h>
static LOut { };
static LOut lo;
template<typename T> inline LOut& operator<<(LOut& mLOut, const T& mValue)
{
std::string str{toStr(mValue)};
std::cout << str;
getLogStream() << str;
return mLOut;
}
用法:
#include <MyLib/Log.h>
...
lo << "hello!" << std::endl;
lo
应static
吗? lo
应extern
吗?
Kudos解释了声明类似cout
的对象的正确方法,并展示了主要标准库的实现方式。
编辑:按cout
- 类似对象,我的意思是在包含相应标题后始终可用的全局变量。
答案 0 :(得分:6)
std::cout
简单地声明如下:
namespace std {
extern ostream cout;
}
这是一个常规的全局变量;你可以自己做同样的事情。将变量的extern
声明放在标题中;然后在源文件中定义相同的变量并将其链接到您的应用程序:
// mylog.h
extern MyLog mylog;
// mylog.cpp
MyLog mylog(someparams);
答案 1 :(得分:1)
首先,我不太清楚你的意思是cout
对象?
也许是std::ostream
。
无论如何,通常的做法是使用过滤 流缓冲。只需编写一个转发到日志文件的streambuf, 除了通常的地方,并把它插入你的地方 想:
class LoggingOutputStreambuf : public std::streambuf
{
std::streambuf* myDest;
std::ofstreambuf myLogFile;
std::ostream* myOwner;
protected:
int overflow( int ch )
{
myLogFile.sputc( ch ); // ignores errors...
return myDest->sputc( ch );
}
public:
LoggingOutputStreambuf(
std::streambuf* dest,
std::string const& logfileName )
: myDest( dest )
, myLogFile( logfileName.c_str(), std::ios_base::out )
, myOwner( nullptr )
{
if ( !myLogFile.is_open() ) {
// Some error handling...
}
}
LoggingOutputStreambuf(
std::ostream& dest,
std::string const& logfileName )
: LoggingOutputStreambuf( dest.rdbuf(), logfileName )
{
dest.rdbuf( this );
myOwner = &dest;
}
~LoggingOutputStreambuf()
{
if ( myOwner != nullptr ) {
myOwner->rdbuf( myDest );
}
}
};
(这是C ++ 11,但要修改它应该不难 C ++ 03)
要使用,您可以使用以下内容:
LoggingOutputStreambuf logger( std::cout );
// ...
std::cout
的所有输出都将被记录,直到logger
结束
范围。
在实践中,你可能会使用比a更复杂的东西
filebuf
用于记录,因为您可能想要插入时间戳
在每一行的开头,或系统地在结束时冲洗
每一行。 (过滤streambufs可以处理这些问题
同样。)
答案 2 :(得分:1)
std :: cout-like对象,它将std :: cout和日志文件都写入
也许boost.iostreams就足够了?
#include <iostream>
#include <fstream>
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/tee.hpp>
namespace io = boost::iostreams;
int main()
{
typedef io::tee_device<std::ostream, std::ofstream> teedev;
typedef io::stream<teedev> LOut;
std::ofstream outfile("test.txt");
teedev logtee(std::cout, outfile);
LOut mLOut(logtee);
mLOut << "hello!" << std::endl;
}
答案 3 :(得分:0)
在我的一个projects中,我为std::cout
编写了包装。
它看起来像这样:
struct out_t {
template<typename T>
out_t&
operator << (T&& x) {
std::cout << x;
// log << x;
return *this;
};
};
out_t out;
out << 1;
要查看完整代码,请在struct out
io.h