什么"朋友std :: ostream&运算符<<(std :: ostream& out,LinkedList& list)"意思?

时间:2016-06-29 07:27:58

标签: c++ linker-errors friend

所以我获得了一个带有入门代码的作业来实现一个链表(我已经成功完成了未分类的双向链表),并且在给定头文件的入门代码中有一个好友声明似乎有允许我使用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;,这让我相信头文件中友元声明的目标是允许列表打印到控制台很容易。通常情况下我不在乎,但如果我没有注释掉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来组合分配,我认为这不是问题。

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;
}

3 个答案:

答案 0 :(得分:9)

  

friend std::ostream& operator<<(std::ostream& out, LinkedList& list)意味着什么

这里的friend declaration首先声明一个非成员函数,并使其成为类的朋友,这意味着它可以访问类LinkedList的私有成员和受保护成员。

  

为什么cout << list;会导致此错误?

因为它只是一个声明,所以你需要自己定义它。这就是为什么你得到一个未定义的引用链接错误。

您可以在类中定义它(即内联定义)

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

或者在课堂外定义:

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

BTW:我建议你制作第二个参数类型const LinkedList&;不应在operator<<内修改它。

答案 1 :(得分:3)

element实际的目标是能够执行e。 G。 std::ostream& operator<<(std::ostream& out, LinkedList& list)

现在你的部分任务就是编写这样一个操作符(至今你还没有这样做,你得到链接器错误......);它将写在你的课堂之外,例如:

std::cout << someList;

到目前为止一切都很好 - 只有一个问题:由于运算符是在类外部定义的,因此它只能访问LinkedList类的公共接口。

这里有朋友宣言:通过这个声明,你明确地允许class LinkedList { /* ... */ }; std::ostream& operator<<(std::ostream& out, LinkedList& list) { /* output the list however it is appropriate */ } 访问私人成员;在你的情况下,特别是operator<<结构和头部和尾部成员,否则所有这些都是操作员无法访问的。

答案 2 :(得分:0)

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

标头声明了友元函数std::ostream& operator<<(std::ostream&, LinkedList&),并在教师编写的main函数中引用它。如果您想要完全归功于作业,则需要实现该功能。 friend限定符意味着这是一个自由函数而不是成员函数,但它可以访问LinkedList对象受保护和私有成员。