How to Properly Overload the ≪≪ Operator For an Ostream

How to properly overload the operator for an ostream?

You have declared your function as friend. It's not a member of the class. You should remove Matrix:: from the implementation. friend means that the specified function (which is not a member of the class) can access private member variables. The way you implemented the function is like an instance method for Matrix class which is wrong.

Are there better ways to overload ostream operator?

I believe that the comments have answered your question well enough. From a pure performance standpoint, there likely is no "better" way to overload the << operator for output streams because your function is likely not the bottleneck in the first place.

I will suggest that there is a "better" way to write the function itself that handles some corner cases.

Your << overload, as it exists now, will 'break' when trying to perform certain output formatting operations.

std::cout << std::setw(15) << std::left << example_ << "Fin\n";

This does not left align your entire Example output. Instead it only left aligns the first_ member. This is because you put your items in the stream one at a time. std::left will grab the next item to left align, which is only a part of your class output.

The easiest way is to build a string and then dump that string into your output stream. Something like this:

friend std::ostream &operator<<(std::ostream &os, const Example &a)
{
std::string tmp = std::to_string(a.first_) + " " + std::to_string(a.second_);
return (os << tmp);
}

It's worth noting a few things here. The first is that in this specific example, you will get trailing 0's because you don't get any control over how std::to_string() formats its values. This may mean writing type-specific conversion functions to do any trimming for you. You may also be able to use std::string_views (to gain back some efficiency (again, it likely doesn't matter as the function itself is probably still not your bottleneck)), but I have no experience with them.

By putting all of the object's information into the stream at once, that left-align will now align the full output of your object.

There is also the argument about friend vs. non-friend. If the necessary getters exist, I would argue that non-friend is the way to go. Friends are useful, but also break encapsulation since they are non-member functions with special access. This gets way into opinion territory, but I don't write simple getters unless I feel that they are necessary, and I don't count << overloads as necessary.

overloading operator c++, I am trying to cout the element of class

It seems you mean the following

std::ostream & operator <<( std::ostream& out, const Box& B) {
return out << B.l << " " << B.b << " " << B.h;
}

provided that all used in the operator data members are public data members of the class Box. The operator shall be declared and defined outside the class definition.

If one of the used data members is a private data member of the class then the function should be a friend function of the class and shall be declared (and may be defined) in the class definition. For example

class Box
{
//...
friend std::ostream & operator <<( std::ostream& out, const Box& B) {
return out << B.l << " " << B.b << " " << B.h;
}
//...
};

Pay attention to that it is better to remove in the return statement the operand std::endl. In this case 1) the operator will be more flexible because you can output additional information in the same line and 2) this statement

std::cout << box;

will not confuse readers of the code because they will not see the operand std::endl.

Without this operand in the operator definition in the caller of the operator you can write

std::cout << box << std::endl;

and this statement more clear expresses the intention of the programmer.

Overloaded operator for ostream syntax

By the way the question was asked and how basic it is, I'm going to try to give a very simplistic (albeit rather informal and not so pedantic) answer.

I don't understand why the overloaded operator takes two parameters
and one being an os object

operator<< is a binary operator. It has a left-hand side and a right-hand side. When you write:

cout << 123;

You are invoking this operator with two operands (arguments): 'cout' on the left and an integer, '123', on the right.

When we were printing out actual linked list objects on main.cpp, we
didn't need to pass an os object.

Your print function is a member function or operator of a class. That would implicitly deduce that the first argument, crudely speaking, does not need to be explicitly passed since you already have the 'this' pointer to work with for your list object. That's not the case with non-member operators as you don't have an implicitly deduced 'this' object to work with already for the left-hand side operand.

When you write code like this:

my_list.print(cout);

You can think of it as actually passing in two arguments, 'my_list' and 'cout'. Even though you don't write it explicitly, you have access to 'my_list' through 'this' along with its members. That's not the case if you wrote the print function as a non-member, like so:

template <class T>
void print(const List<T>& my_list, ostream& os);

That's also the case with your operator which is not a member function.

Also, why is it returning os?

Returning a reference to ostream is what allows us to write statements like this:

cout << "hello " << "world";

First we invoke operator<<(cout, "hello ") which then gives us another ostream reference to work with which then allows us to proceed to invoke operator<<(cout, "world"). If it returned void, for example, it would not allow us to invoke that operator twice in one statement since we'd be trying to output "world " with void as the left-hand operand.

Why can't we just use cout instead of "os <<" ?

cout basically implements the ostream interface. So does ofstream, ostringstream, and other types of output streams. By writing it in terms of the basic interface required and not some specific ostream derivative, you allow the code you write to work with stdio streams, file streams, stream streams, and others. Basically it makes your code very general and reusable which is something you should strive to do when practical. You'll learn about this subject more as you tackle the concept of polymorphism.

Overloading operator for std::ostream

You should define summartReport taking ostream& as parameter, as shown here:

std::ostream&  storageRentals::summaryReport(std::ostream & out) const
{
//use out instead of cout
for (int count = 0; count < 8; count++)
out << "Unit: " << count + 1 << " " << stoUnits[count] << endl;

return out; //return so that op<< can be just one line!
}

then call it as:

ostream& operator <<(ostream& osObject, const storageRentals& rentals)
{
return rentals.summaryReport(osObject); //just one line!
}

By the way, it is not called "overloading cout". You should say, "overloading operator<< for std::ostream.

Overloading the ostream operator for a class wrapping stringstream

Here is the solution

#include <iostream>
#include <sstream>
#include <mutex>

using namespace std;

class MutexWrapper
{
private:
mutex& m_mutex;
public:
MutexWrapper(mutex& mtx) : m_mutex(mtx) { mtx.lock () ; };
~MutexWrapper() { m_mutex.unlock () ; };
};

class WrappedStringStream
{
public :
WrappedStringStream() { };

template<typename T>
std::ostream & operator<<(const T& value)
{
MutexWrapper wrapper(m_mutex);
return m_stringstream << value;
}

void showStream()
{
cout << m_stringstream.str();
}

protected :
stringstream m_stringstream;
mutable mutex m_mutex ;
};

int main()
{
WrappedStringStream ws;

ws << "This is a string, " << 5 << 6.78;
ws.showStream();

return 0;
}

Output

This is a string, 56.78

======== edit ==========

Originally I was not quiet understand what the questioner's final goal, but just focus on how to fix his syntax issue.It is not a good idea to use << in a multithreading environment. We have a Log class, and in our log class we only have a Log method which takes variable amount of parameters. That will solve the problem.

Still, there is a solution for using << to lock the thread, but really urgly and NOT recommend. Downside is obvious - if you forgot to add the 'LoggingStart' and 'LoggingEnd', you might caught deadlock.

Also thanks @RemyLebeau, It should return *this instead of m_stringstream.

Please see code below.

#include <iostream>
#include <sstream>
#include <mutex>

using namespace std;

class WrappedStringStream
{
public:
enum StreamSignals
{
LoggingStart,
LoggingEnd
};

WrappedStringStream() { };

std::ostream & operator<<(const StreamSignals& signal)
{
if (signal == LoggingStart)
m_mutex.lock();
else if (signal == LoggingEnd)
m_mutex.unlock();

return *this;
}

template<typename T>
std::ostream & operator<<(const T& value)
{
m_stringstream << value;
return *this;
}

void showStream()
{
cout << m_stringstream.str();
}

protected :
stringstream m_stringstream;
mutable mutex m_mutex ;
};

int main()
{
WrappedStringStream ws;

ws << WrappedStringStream::StreamSignals::LoggingStart;
ws << "This is a string, " << 5 << 6.78;
ws << WrappedStringStream::StreamSignals::LoggingEnd;
ws.showStream();

return 0;
}

Overloading ostream operator () for class defined within a namespace

Question:

is this the correct way of solving this problem?

Answer:

Yes, it is the correct way of solving the problem.

Question:

Isn't this approach giving away details of the implementation?

Answer:

Not at all.

The line

friend std::ostream& operator <<(std::ostream& output, const Bar&);

declares the function as an external function in the namespace in which the class is defined. If the class is not defined in a namespace, the function is declared as an external function in the global namespace. Since the function is declared as a external function in the foo namespace, it MUST be defined in that namespace.

If you want that function to be a global function, outside the foo namesapce, you have to use:

namespace foo
{
class Bar;
}

std::ostream& operator <<(std::ostream& output, const foo::Bar&);

namespace foo {

class Bar {
public:
friend std::ostream& operator <<(std::ostream& output, const Bar&);
private:
int xx_;
};
}

How to properly overload the stream operator for printing in an polymorphic class?

The solution is very simple.

  1. Define the operator<< function only for the base class. There is no need to define it for the derived types.
  2. Rely on the virtual function mechanism to invoke the print function of the derived class.
  3. Add code to call Base::print from the derived classes before printing the derived class specific content. Make sure the function is not private in the base class.

#include <iostream>

class Base {
protected:
virtual std::ostream & print(std::ostream& stream) const {
stream << "Base class output\n";
return stream;
}

public:

// Define it only for the base class.
friend std::ostream & operator<<(std::ostream & stream, const Base & obj) {
return obj.print(stream);
}

virtual ~Base() {}
};

class A : public Base {

std::ostream & print(std::ostream & stream) const {
// Print the base class specific information first.
Base::print(stream);

// Print the derived class specific information.
stream << "foo = " << foo << "\n";
return stream;
}

int foo = 0;
public:
~A() {}
};

class B : public Base {

std::ostream & print(std::ostream & stream) const {
// Print the base class-specific information first.
Base::print(stream);

// Print the derived class specific information.
stream << "bar = " << bar << "\n";
return stream;
}

int bar = 0;
public:
~B() {}
};

With those changes, I get the desired output. See it working at https://ideone.com/x6ti3W.



Related Topics



Leave a reply



Submit