2

I want to overload the operator << to print a list using std::cout, for example:

std::cout << list 
//ouputs as {1,2,3,..}

After searching, I came to know that this can be done using ostream, but I am not sure how this is done. Like why is this necessary to take in ostream as a reference and then return it?

Operator Overloading function:

ostream& operator<<(ostream& os, List list) 
{
    Node* temp = list.start; //points to the start of the list
    cout<<"{";
    while(temp)
    {
        cout << temp->data; //cout all the data
        if (temp->next != NULL)
            cout << ",";
        temp = temp->next;
    }
    cout<<"}" << endl;
    return os; //returns the ostream
}

And I also don't understant why do we have to make that a friend function? If I remove the keyword friend, it gives me an error that << operator is a binary operator. I am using Xcode.

List.hpp

class List
{
    Node* start;
public:
    List();
    ~List();
    void emptyList();
    void append(int);
    void insert(int, int);
    void print();
    int  length();
    void remove_at(int);
    int get_value_index(int);
    int get_value_at(int);
    List operator-(int); 
    friend ostream& operator<<(ostream& os,List); //why friend function??
    List operator=(List);
    List operator+(int);
    List operator+(List);
    int& operator[](const int ind);
    bool operator==(List);
};
Matthias
  • 4,481
  • 12
  • 45
  • 84
Aiman Khan
  • 21
  • 1
  • 2
  • The hows and whys are covered in the discussion here: https://stackoverflow.com/q/2828280/1531971 –  Oct 17 '17 at 15:21
  • return stream from << so that you can chain operations `cout << 42 << mylist << "yo"` – pm100 Oct 17 '17 at 15:49
  • Just to bring some clarity: you can define `void operator>>(ostream& os);` in your `class List` instead and call it as `list >> cout;`. Not recommended, just to illustrate. – KonstantinL Oct 17 '17 at 15:49

2 Answers2

3

In the operator << overload you shouldn’t use cout, you should use the ostream you are receiving as a parameter, just change the cout for os. This is because the cout will print that output stream you are returning.

You need to make that operator overload a friend function because even though the operator isn’t a part of the class, it will have access to the class private attributes and functions, so it can access the elements and print them.

  • 3
    To be clear. If you are able to convert your class to a printable string without accessing private methods or data the `friend` is not needed. One useful approach to avoiding the `friend` is to define a public `toString()` method on the class and implement as `os << list.toStringIO;` – Dale Wilson Oct 17 '17 at 15:48
1

The operator << is a binary operator, meaning that it needs one operand on the left-hand side and one on the right-hand side. For example, when you write cout << "Hello World" the left-hand side operand is cout which is of type ostream and the right-hand side operand is the string "Hello World". Similarly, to overload the operator for one of your classes you must define what will be the left-hand side operand and what the right-hand side operand, just as overloading the plus (+) operator, or any other binary operator, requires you to define what are the operands. Therefore, os should be used where you have written cout, as has already been pointed out in a previous answer, and it will have the "value" cout if the left-hand side opernad is cout.

As for returning os, the reason to do this is in order to be able to chain multiple printing statements. It is possible using integers to write cout << 3 << 5;, because initially the first << operator is evaluated, printing 3, then os is returned and is passed as the left-hand side operand to the next <<. If the overloaded operator does not return os, this will be impossible to do with objects of your class.

Finally, as has already been said, the overload should be a friend of the class because it needs access to its private members, and since it is not a member function of the class, it cannot have it unless it is a friend to it.