简体   繁体   中英

What does “friend std::ostream& operator<<(std::ostream& out, LinkedList& list)” mean?

So I was given an assignment with starter code to implement a linked list (which I have done with an unsorted doubly linked list successfully) and in the starter code in the given header file there was a friend declaration that seems to have the goal of allowing me to print the linked list using the cout statement. This is the header file; note that I wrote everything in the private section.

#ifndef _LINKED_LIST_
#define _LINKED_LIST_

#include <ostream>

class LinkedList
{
public:
    LinkedList();
    ~LinkedList();

    void add(char ch);
    bool find(char ch);
    bool del(char ch);

    friend std::ostream& operator<<(std::ostream& out, LinkedList& list);

private:
    struct node
    {
        char data;
        node * next;
        node * prev;
    };
    node * head, * tail;
};

#endif // _LINKED_LIST_

In main , which was also part of the starter code, the teacher wrote cout << list; which leads me to believe the goal of the friend statement in the header file was to allow list to be printed to the console easily. Normally I wouldn't care but if I don't comment out the cout << list; statements then the linker gives me the following error for every instance of cout << list;

app.o: In function 'main':
[code directory]/app.cpp:[line the statement is on]: undefined reference to
'operator<<(std::ostream&, LinkedList&)'

My question is , what does friend std::ostream& operator<<(std::ostream& out, LinkedList& list) mean and why does cout << list; cause this error? The code executes fine without the statements and since I'm using the instructor's makefile to assemble the assignment, I figure that isn't the issue.

app.cpp is as follows

#include <iostream>
#include "linkedlist.h"

using namespace std;

void find(LinkedList& list, char ch)
{
    if (list.find(ch))
        cout << "found ";
    else
        cout << "did not find ";
    cout << ch << endl;
}

int main()
{
    LinkedList  list;

    list.add('x');
    list.add('y');
    list.add('z');
    cout << list;
    find(list, 'y');

    list.del('y');
    cout << list;
    find(list, 'y');

    list.del('x');
    cout << list;
    find(list, 'y');

    list.del('z');
    cout << list;
    find(list, 'y');

    return 0;
}

what does friend std::ostream& operator<<(std::ostream& out, LinkedList& list) mean

The friend declaration declares a non-member function, and makes it friend of the class, meaning it can access the private and protected members of the class LinkedList .

and why does cout << list; cause this error?

Since it's just a declaration, you need to define it by yourself. That's why you get an undefined reference linker error.

You might define it inside the class (and defined inline)

class LinkedList
{
    ...
    friend std::ostream& operator<<(std::ostream& out, LinkedList& list) {
        // output something
        return out;
    }
    ...
};

Or define it outside of the class:

std::ostream& operator<<(std::ostream& out, LinkedList& list) {
    // output something
    return out;
}

BTW: I suggest you to make the 2nd parameter type const LinkedList& ; it should not be modified inside the operator<< .

The goal of std::ostream& operator<<(std::ostream& out, LinkedList& list) actually is to be able to do eg std::cout << someList;

Part of your task now is to write such an operator (and as you haven't done so so far, you get the linker error...); it will be written outside of your class, such as this:

class LinkedList
{
    /* ... */
};

std::ostream& operator<<(std::ostream& out, LinkedList& list)
{
    /* output the list however it is appropriate */
}

This is all fine so far - only one single problem: As the operator is defined outside the class, it can only access the public interface of the LinkedList class.

And here comes the friend declaration into play: With this declaration, you explicitely allow the operator<< to access the private members, too; in your case especially the node struct and the head and tail members which otherwise all would have been inaccessible for the operator.

You have guessed correctly that the goal of that function is to print an instance of the class to the provided output stream. When used in this context (two arguments, a reference to an output stream and a reference to an object of some kind, and returning the stream), the << operator is typically called the stream insertion operator.

The header declares the friend function std::ostream& operator<<(std::ostream&, LinkedList&) , and it is referenced in the main function written by the instructor. If you want full credit for the assignment, you need to implement that function. The friend qualifier means that this is a free function rather than a member function but that it can access a LinkedList objects protected and private members.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM