473,328 Members | 1,546 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,328 software developers and data experts.

Help with operator overloading of <<

Hi,
I'm trying to play with classes and I'm having trouble with a
theoretical
problem.

I've create a 'Log' class, who creates and writes to log files. I was
able
to overload the << operator so that I could write to my log as follows:

Log logOne("log.txt", true, "\n" );
logOne<<"BLAH"<<"BLAH2";

In the constructor, the 'true' refers to having the log class write out
a
datetime stamp of each log entry, while the '\n' indicates how to
terminate
the log line.

The problem is that when I use the syntax about (<<"A"<<"B" ), etc, it
ends
up writing multiple lines because the << function is getting called
each
time. What I would like to do is have A and B be concatenated into one
string and then do the actual call to write the log line once. How do I
know
if I am the 'LAST' item being sent to the << so that I can store the
intermediate values and not write it out unless I am last?

Here is my function: (quite simple)
Log & operator << (string a)
{
writeLog(a);
return *this;
}
Thanks in advance...

Jul 23 '05 #1
4 1385

"winbatch" <ho********@gmail.com> wrote in message
news:11*********************@o13g2000cwo.googlegro ups.com...
Hi,
I'm trying to play with classes and I'm having trouble with a
theoretical
problem.

I've create a 'Log' class, who creates and writes to log files. I was
able
to overload the << operator so that I could write to my log as follows:

Log logOne("log.txt", true, "\n" );
logOne<<"BLAH"<<"BLAH2";

In the constructor, the 'true' refers to having the log class write out
a
datetime stamp of each log entry, while the '\n' indicates how to
terminate
the log line.

The problem is that when I use the syntax about (<<"A"<<"B" ), etc, it
ends
up writing multiple lines because the << function is getting called
each
time.
Operator << must (!) be called here twice because you call it twice ;-) So
that behavior absolutely makes sense.
What I would like to do is have A and B be concatenated into one
string and then do the actual call to write the log line once. How do I
know
if I am the 'LAST' item being sent to the << so that I can store the
intermediate values and not write it out unless I am last?

Here is my function: (quite simple)
Log & operator << (string a)
{
writeLog(a);
return *this;
}


Without seeing the writeLog(a) function this code snippet is not worth very
much, but there are some things that are visible right away. First of all
you should pass a const string reference instead of the string object. This
has nothing to do with your problem but youŽll save yourself unnecessary
copies of the string object.
Despite this your problem is located in the writeLog function which I assume
will look something like this:

void writeLog( string Text ) {
cout << m_Date << " " << Text << endl;
}

And here it is - the end of line manipulator endl. Just skip it and all
strings are going to be output on the same line. However, you should
terminate the line yourself sending the endl or "\n" to the stream after the
last thing you want to output. In principle it works just like the normal
cout stream.

Cheers
Chris
Jul 23 '05 #2
Chris,

I don't have an endl in my writeLog function. The reason is that the
constructor takes a parameter which will be the EOL for the log. The reason
for this is that I have another class which contains multiple logs and I
just send it a string and it will call the writeLog of each of the Log
objects inside. Since certain logs will have different terminators, I
didn't want to have to deal with this when I passed the string to be logged,
but rather it be part of the Log object itself.

I realize that the << is being called twice, and that's exactly the problem.
I only want the log to be written to the file when I'm on the LAST call to
the <<. All previous calls should simply append the string to some buffer
so that when I hit the last call to <<, I can write out my buffer (with the
last string included).

This is the writeLog function for your reference. Regarding your advice
about const, I have taken your advice.

void Log::writeLog( const string &logLine )
{
content=logLine;
if ( !out->is_open() )
throw DHException( 3, "Attempt to write to log file [", fileName.c_str(),
"] without opening first!");

if ( includeDate )
{
current.now();
content = Date::getFormattedDate( current ) +">" + content + suffix;
}
out->write( content.c_str(), content.size() );
out->flush();

if ( !out->is_open() )
throw DHException ( 3, "Could not write to log file [", fileName.c_str(),
"] !");

}

"Chris Theis" <Ch*********@nospam.cern.ch> wrote in message
news:cu**********@sunnews.cern.ch...

"winbatch" <ho********@gmail.com> wrote in message
news:11*********************@o13g2000cwo.googlegro ups.com...
Hi,
I'm trying to play with classes and I'm having trouble with a
theoretical
problem.

I've create a 'Log' class, who creates and writes to log files. I was
able
to overload the << operator so that I could write to my log as follows:

Log logOne("log.txt", true, "\n" );
logOne<<"BLAH"<<"BLAH2";

In the constructor, the 'true' refers to having the log class write out
a
datetime stamp of each log entry, while the '\n' indicates how to
terminate
the log line.

The problem is that when I use the syntax about (<<"A"<<"B" ), etc, it
ends
up writing multiple lines because the << function is getting called
each
time.


Operator << must (!) be called here twice because you call it twice ;-) So
that behavior absolutely makes sense.
What I would like to do is have A and B be concatenated into one
string and then do the actual call to write the log line once. How do I
know
if I am the 'LAST' item being sent to the << so that I can store the
intermediate values and not write it out unless I am last?

Here is my function: (quite simple)
Log & operator << (string a)
{
writeLog(a);
return *this;
}


Without seeing the writeLog(a) function this code snippet is not worth
very
much, but there are some things that are visible right away. First of all
you should pass a const string reference instead of the string object.
This
has nothing to do with your problem but youŽll save yourself unnecessary
copies of the string object.
Despite this your problem is located in the writeLog function which I
assume
will look something like this:

void writeLog( string Text ) {
cout << m_Date << " " << Text << endl;
}

And here it is - the end of line manipulator endl. Just skip it and all
strings are going to be output on the same line. However, you should
terminate the line yourself sending the endl or "\n" to the stream after
the
last thing you want to output. In principle it works just like the normal
cout stream.

Cheers
Chris

Jul 23 '05 #3
GB
winbatch wrote:
I've create a 'Log' class, who creates and writes to log files. I was
able
to overload the << operator so that I could write to my log as follows:

Log logOne("log.txt", true, "\n" );
logOne<<"BLAH"<<"BLAH2";

In the constructor, the 'true' refers to having the log class write out
a
datetime stamp of each log entry, while the '\n' indicates how to
terminate
the log line.

The problem is that when I use the syntax about (<<"A"<<"B" ), etc, it
ends
up writing multiple lines because the << function is getting called
each
time. What I would like to do is have A and B be concatenated into one
string and then do the actual call to write the log line once. How do I
know
if I am the 'LAST' item being sent to the << so that I can store the
intermediate values and not write it out unless I am last?


Instead of writing the timestamp from within the insertion function,
require that it be added explicitly. You can do this by defining your
own timestamp stream manipulator, logstamp, which you would then use
like this:

log << logstamp << "blah1" << "blah2" << std::endl;
I have done something similar to this. Another thing I have done to make
the log thread-safe is to take advantage of the C++ property that
temporary objects are guaranteed not to be destroyed until the entire
expression in which it appears is evaluated. I take advantage of this by
acquiring a log mutex in logstamp's constructor and releasing it in its
destructor. That way the entire string of insertions is guaranteed to be
atomic. No need for printf-style output mechanism. Details are
off-topic, though.

Gregg
Jul 23 '05 #4

"Dan Hoffman" <da********@nyc.rr.com> wrote in message
news:w0***************@twister.nyc.rr.com...
Chris,

I don't have an endl in my writeLog function. The reason is that the
constructor takes a parameter which will be the EOL for the log. The reason for this is that I have another class which contains multiple logs and I
just send it a string and it will call the writeLog of each of the Log
objects inside. Since certain logs will have different terminators, I
didn't want to have to deal with this when I passed the string to be logged, but rather it be part of the Log object itself.

I realize that the << is being called twice, and that's exactly the problem. I only want the log to be written to the file when I'm on the LAST call to
the <<. All previous calls should simply append the string to some buffer
so that when I hit the last call to <<, I can write out my buffer (with the last string included).

This is the writeLog function for your reference. Regarding your advice
about const, I have taken your advice.

void Log::writeLog( const string &logLine )
{
content=logLine;
if ( !out->is_open() )
throw DHException( 3, "Attempt to write to log file [", fileName.c_str(),
"] without opening first!");

if ( includeDate )
{
current.now();
content = Date::getFormattedDate( current ) +">" + content + suffix;
}
out->write( content.c_str(), content.size() );
out->flush();

if ( !out->is_open() )
throw DHException ( 3, "Could not write to log file [", fileName.c_str(), "] !");

}

"Chris Theis" <Ch*********@nospam.cern.ch> wrote in message
news:cu**********@sunnews.cern.ch...

"winbatch" <ho********@gmail.com> wrote in message
news:11*********************@o13g2000cwo.googlegro ups.com...
Hi,
I'm trying to play with classes and I'm having trouble with a
theoretical
problem.

I've create a 'Log' class, who creates and writes to log files. I was
able
to overload the << operator so that I could write to my log as follows:

Log logOne("log.txt", true, "\n" );
logOne<<"BLAH"<<"BLAH2";

In the constructor, the 'true' refers to having the log class write out
a
datetime stamp of each log entry, while the '\n' indicates how to
terminate
the log line.

The problem is that when I use the syntax about (<<"A"<<"B" ), etc, it
ends
up writing multiple lines because the << function is getting called
each
time.


Operator << must (!) be called here twice because you call it twice ;-) So that behavior absolutely makes sense.
What I would like to do is have A and B be concatenated into one
string and then do the actual call to write the log line once. How do I
know
if I am the 'LAST' item being sent to the << so that I can store the
intermediate values and not write it out unless I am last?

Here is my function: (quite simple)
Log & operator << (string a)
{
writeLog(a);
return *this;
}


Hi Dan,

I personally would find it clearer to implement the date/time stamp as a
manipulator as already recommended in another posting. Otherwise you could
implement your log to buffer the strings until your own user supplied endl -
manipulator signals a flush.

Cheers
Chris
Jul 23 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Victor | last post by:
Anyone knows how to write a virtual function for operator<< ? I have a base class and some public derived class from it. For the derived class, I hope they can use << to output their different...
2
by: Julian | last post by:
I would like to have output from my program to be written to cout as well as a file. (actually, i want several other output options but this should explain my problem in the simplest way). I have...
2
by: pmatos | last post by:
Hi all, I'm overloading operator<< for a lot of classes. The question is about style. I define in each class header the prototype of the overloading as a friend. Now, where should I define the...
4
by: bart.kowalski | last post by:
Hello, I'm trying to overload operator << for class CString, which has an operator const char *. I thought the following code would do: template <typename T> inline std::basic_ostream<T>...
8
by: jois.de.vivre | last post by:
Hi, I'm having some trouble overloading the << operator. I have the following, very simple code: #include <iostream> using namespace std; class test { private: int val;
5
by: Ian Lazarus | last post by:
Hello, My question is whether it is possible to avoid assignment on the left hand side of an overloaded operator << expression, as in the code below. Without the assignment, the compiler...
17
by: Ashwin | last post by:
hi guys, i have overloaded the << operator.as shown below. ostream& operator<<(ostream &out, const student &a) { out<<a.idno; out<< " " ; // out<< a.name; out<< " " ; // out<< a.marks...
6
by: iLL | last post by:
Okay, I’m just a little confused on exactly what the system is doing when I say: #include <iostream> class test { private: int i; public:
3
by: subramanian100in | last post by:
Consider the code: #include <iostream> using namespace std; int main( ) { cout << "test string "; cout.operator<<(10).operator<<(endl);
8
by: Goran | last post by:
Hi all, I have a question regarding operator <<. A lib of mine contains a class with an overloaded operator << as NON- class member. This would look like: #include <iostream> #include...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.