"friend std::ostream& operator<<(std::ostream& out, LinkedList& list)" 是什么意思?

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

所以我得到了一个带有起始代码的任务来实现一个链表(我已经成功地完成了一个未排序的双向链表)并且在给定头文件的起始代码中有一个朋友声明似乎目标是允许我使用 cout 语句打印链表。这是头文件;请注意,我在私人部分写了所有内容。

#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_

main 中,这也是起始代码的一部分,老师写了 cout << list; 这让我相信头文件中的 friend 语句的目标是允许列表轻松打印到控制台。通常我不会在意,但如果我不注释掉 cout << list; 语句,那么链接器会为 cout << list;

的每个实例提供以下错误
app.o: In function 'main':
[code directory]/app.cpp:[line the statement is on]: undefined reference to
'operator<<(std::ostream&, LinkedList&)'

我的问题是friend std::ostream& operator<<(std::ostream& out, LinkedList& list)是什么意思,为什么cout << list;会导致这个错误?代码在没有语句的情况下执行良好,因为我使用教师的 makefile 来 assemble 作业,我认为这不是问题。

app.cpp如下

#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

friend declaration 声明了一个非成员函数,并使其成为 class 的友元函数,这意味着它可以访问 privateprotected 成员=32=] LinkedList.

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

由于只是声明,所以需要自己定义。这就是您收到未定义的引用链接器错误的原因。

您可以在 class 中定义它(并内联定义)

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

或者在class之外定义它:

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

顺便说一句:我建议你将第二个参数设为const LinkedList&;不应在 operator<<.

内修改

std::ostream& operator<<(std::ostream& out, LinkedList& list)的目标实际上能够做到e。 G。 std::cout << someList;

你现在的部分任务是编写这样一个运算符(由于你到目前为止还没有这样做,你会遇到链接器错误...);它会写在你的 class 之外,例如:

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

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

到目前为止一切正常 - 只有一个问题:由于运算符定义在 class 之外,它只能访问 LinkedList class 的 public 接口。

友元声明开始发挥作用:有了这个声明,您也明确允许 operator<< 访问私有成员;在您的情况下,尤其是 node 结构和头部和尾部成员,否则操作员将无法访问这些成员。

您猜对了,该函数的目标是将 class 的实例打印到提供的输出流。在此上下文中使用时(两个参数,对输出流的引用和对某种对象的引用,以及返回流),<< 运算符通常称为流插入运算符。

header声明了友元函数std::ostream& operator<<(std::ostream&, LinkedList&),在导师写的main函数中引用了。如果您想要获得作业的全部学分,则需要实现该功能。 friend 限定符表示这是一个自由函数而不是成员函数,但它可以访问 LinkedList 对象的受保护成员和私有成员。