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.