Overload << Operator with Input Parameter
Apr 7, 2013 at 4:13pm UTC
Hi,
Here is what I am looking to do:
1 2 3 4 5 6
// class constructor as log file input
Logger log(file_name);
// input argument as the log level
// stream overload - log text
log(LOG_DEBUG) << "log text here" ;
// LOG_DEBUG is an enum in the header
I have everything working in Qt using a QTextStream for the output stream to send the data to the log file. The only issue that I am having is the input argument to the log statement (LOG_DEBUG), in which I am unsure in how to accomplish this. I know this isn't a Qt forum, but I feel like this is a general c++ question.
Here is my Qt code so far:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
#include <QObject>
#include <QTextStream>
#include <QFile>
#include <QDebug>
enum LogLevels {
LOG_WARNING = 0,
LOG_INFO,
LOG_DEBUG
};
class Logger : public QObject
{
Q_OBJECT
public :
Logger(QString file_name){
file = new QFile(file_name);
if (!file->open(QIODevice::WriteOnly)){
qDebug() << "failed to open file" ;
}
out_stream = new QTextStream(file);
}
~Logger()
{
file->close();
delete file;
delete out_stream;
}
template <typename T>
friend Logger& operator << (Logger& logger, T thing) {
*logger.out_stream << thing;
*logger.out_stream << "\n" ;
logger.out_stream->flush();
return logger;
}
friend Logger& operator << (Logger& logger, QVariant thing) {
*logger.out_stream << thing.toString();
*logger.out_stream << "\n" ;
logger.out_stream->flush();
return logger;
}
private :
QTextStream* out_stream;
QFile *file;
};
This code works as follows:
1 2
Logger log("/home/path/to/logfile.txt" );
logger << "Here is some log text to stream" ;
Could anyone point me in the right direction? I think I am close.
Apr 7, 2013 at 4:46pm UTC
1 2 3 4
Logger& Logger::operator ()(LogLevels level){
//...
return *this ;
}
friend Logger& operator << (Logger& logger, T thing)
¿why isn't that a member function?
Also, ¿why are you using dynamic allocation?
Last edited on Apr 7, 2013 at 4:47pm UTC
Apr 7, 2013 at 5:16pm UTC
Hi,
Thank you for the reply.
I used the * for the file and stream because I thought at some point I might want to make the class so that I would be able to change the stream to something else other than a QTextStream.
For some reason I was unable to get the templates to work for the stream operators as a member function. I thought if you were overriding the stream operators you cannot define them in your class header? Thats why I had them the way that they are.
I re-wrote some of the class to look like this (under the assumption that you can make them member functions):
Heres my class .h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
#ifndef LOGGERSTREAM_H
#define LOGGERSTREAM_H
#include <QObject>
#include <QTextStream>
#include <QFile>
#include <QDebug>
class LoggerStream : public QObject
{
Q_OBJECT
public :
LoggerStream(QString file_name);
~LoggerStream();
private :
QTextStream* out_stream;
QFile file;
};
#endif // LOGGERSTREAM_H
Heres my class .cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
LoggerStream::LoggerStream(QString file_name)
{
file.setFileName(file_name);
if (!file.open(QIODevice::WriteOnly)){
qDebug() << "failed to open file" ;
}
out_stream = new QTextStream(&file);
}
template <typename T>
LoggerStream& LoggerStream::operator << (LoggerStream& logger, T thing)
{
*logger.out_stream << thing;
*logger.out_stream << "\n" ;
logger.out_stream.flush();
return logger;
}
LoggerStream& LoggerStream::operator << (LoggerStream& logger, QVariant thing)
{
*logger.out_stream << thing.toString();
*logger.out_stream << "\n" ;
logger.out_stream.flush();
return logger;
}
LoggerStream::~LoggerStream()
{
file.close();
delete out_stream;
}
I am getting the following compilation errors (which I what I was getting before when I tried to make them class members):
loggerstream.cpp:13: error: 'LoggerStream& LoggerStream::operator<<(LoggerStream&, T)' must take exactly one argument
Last edited on Apr 7, 2013 at 5:18pm UTC
Apr 7, 2013 at 5:28pm UTC
> must take exactly one argument
LoggerStream& LoggerStream::operator << (T thing)
the left operand is this
Also, you must define template functions in the header.
By the way, as you need a destructor you'll also need a copy constructor and an assignment operator
Apr 7, 2013 at 5:42pm UTC
Again, thank you very very much for the help. It does work now as member functions as the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
#ifndef LOGGERSTREAM_H
#define LOGGERSTREAM_H
#include <QObject>
#include <QTextStream>
#include <QFile>
#include <QDebug>
enum LogLevels {
LOG_WARNING = 0,
LOG_INFO,
LOG_CRITICAL,
LOG_DEBUG1,
LOG_DEBUG2,
LOG_DEBUG3
};
class LoggerStream : public QObject
{
Q_OBJECT
public :
LoggerStream(QString file_name);
~LoggerStream();
template <typename T> LoggerStream & operator << (T thing);
LoggerStream & operator << (QVariant thing);
private :
QTextStream* out_stream;
QFile file;
};
#endif // LOGGERSTREAM_H
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
#include "loggerstream.h"
LoggerStream::LoggerStream(QString file_name)
{
file.setFileName(file_name);
if (!file.open(QIODevice::WriteOnly)){
qDebug() << "failed to open file" ;
}
out_stream = new QTextStream(&file);
}
template <typename T>
LoggerStream& LoggerStream::operator << (T thing)
{
*this ->out_stream << thing;
*this ->out_stream << "\n" ;
this ->out_stream->flush();
return *this ;
}
LoggerStream& LoggerStream::operator << (QVariant thing)
{
*this ->out_stream << thing.toString();
*this ->out_stream << "\n" ;
this ->out_stream->flush();
return *this ;
}
LoggerStream::~LoggerStream()
{
file.close();
delete out_stream;
}
Yet I still don't see how the syntax would work for adding the log levels as an input argument as you posted before?
1 2 3 4 5
Logger& Logger::operator ()(LogLevels level)
{
//...
return *this ;
}
I guess I dont really get the concept of adding an argument after the operator.
Edt: I got it, thank you so much again for the help!
Last edited on Apr 7, 2013 at 5:45pm UTC
Topic archived. No new replies allowed.