【问题标题】:C++: Making a function friend of multiple classes?C++:让多个类成为函数的朋友?
【发布时间】:2020-05-17 11:01:34
【问题描述】:

这是我写的一个双向链表类:

template <class T>
class DLL
{
    class Node
    {
        T m_data;
        Node* m_prev;
        Node* m_next;

        Node(const T& data) :m_data{ data }, m_prev{ nullptr }, m_next{ nullptr }{}

        friend class DLL;

        friend std::ostream& operator<<(std::ostream& out, const Node& node)
        {
            out << node.m_data;
            return out;
        }
    };

    Node* m_first = nullptr;

public:
    DLL& add(const T& data)
    {
        Node* temp = new Node{ data };

        if (m_first)
        {
            temp->m_next = m_first;
            m_first->m_prev = temp;
            m_first = temp;
        }
        else {
            m_first = temp;
        }
        return *this;
    }

    friend std::ostream& operator<<(std::ostream& out, const DLL& dll)
    {
        Node* trav = dll.m_first;
        while (trav)
        {
            out << *trav << ' ';
            trav = trav->m_next; //C2248: Cannot access private member declared in class DLL::Node.
        }
        return out;
    }

    ~DLL()
    {
        Node* trav = m_first->m_next;
        Node* foll = m_first;

        while (trav)
        {
            delete foll;
            foll = trav;
            trav = trav->m_next;
        }
        delete foll;
    }
};

DLL 的友元函数中将DLL 输出到流中,弹出错误提示该函数无法访问类Node 的私有成员。

经过几次尝试,我想出了一个解决方案,将这个朋友函数声明为Node 类的朋友,如下所示:

class Node
    {
        T m_data;
        Node* m_prev;
        Node* m_next;

        Node(const T& data) :m_data{ data }, m_prev{ nullptr }, m_next{ nullptr }{}

        friend class DLL;

        friend std::ostream& operator<<(std::ostream& out, const Node& node)
        {
            out << node.m_data;
            return out;
        }

        friend std::ostream& operator<<(std::ostream& out, const DLL& dll);
    };

现在std::ostream&amp; operator&lt;&lt;(std::ostream&amp; out, const DLL&amp; dll) 函数可以访问Node 类中的m_next 并且一切正常……或者我认为是这样。

我的问题是:一个函数是否可以像我们在这里看到的那样成为多个类的朋友,或者我所做的事情是否会引发未定义的行为?

【问题讨论】:

  • 注意:DLL 通常表示“动态链接库”,而不是“双向链表”。
  • @Nelfeal 我知道。我这样做是因为我只是想制作一个双向链表。我不会在任何生产代码中实现它:)

标签: c++ oop friend friend-function


【解决方案1】:

是的,一个函数可以是多个类的朋友。

但是好友不是继承的,所以即使operator&lt;&lt;DLL&lt;T&gt;的好友,而DLL&lt;T&gt;DLL&lt;T&gt;::Node的好友,它也不会自动使operator&lt;&lt;成为DLL&lt;T&gt;::Node的好友,因此它无法访问private DLL&lt;T&gt;::Node::m_next

解决方案是像您一样将其声明为DLL&lt;T&gt;::Node 的朋友。

【讨论】:

    【解决方案2】:

    某个类中的友元函数声明仅指定该函数为该类的友元,而不是成员。您绝对可以成为多个类的函数朋友。例如:

    class B;
    
    class A {
        int a = 2;
        friend auto operator+(A a, B b) -> int;
    };
    
    class B {
        int b = 5;
        friend auto operator+(A a, B b) -> int;
    };
    
    auto operator+(A a, B b) -> int {
        return a.a + b.b;
    }
    

    Demo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-16
      • 2016-11-26
      • 2010-10-16
      • 1970-01-01
      • 2011-05-20
      • 1970-01-01
      相关资源
      最近更新 更多