友元函数无法访问私有成员

Friend function cannot access private members

在阅读 C++ Primer 时,我遇到了以下代码片段(我省略了我认为不相关的代码):

class Message {
  friend class Folder;

 public:
  // ...

 private:
  std::string contents;
  std::set<Folder*> folders;
  // ...
};

// ...
void swap(Message& lhs, Message& rhs) {
  using std::swap;
  for (auto f : lhs.folders) { f->remMsg(&lhs); }
  // class Folder is undefined by book
  // ...
}
// ...

C++ Primer 给出了实现 class Folder 的任务。所以我添加了更多代码::

class Folder;   // my code

class Message {
  friend void swap(Message&, Message&);  // my code
  friend class Folder;

 public:
  // ...

 private:
  std::string contents;
  std::set<Folder*> folders;
  // ...
};

void swap(Message&, Message&);  // my code

// I added the whole class
class Folder {
  friend void swap(Folder&, Folder&);
  friend class Message;

 public:
  // ...

 private:
  // ...
  void addMsg(Message* m) { msgs.insert(m); }
  void remMsg(Message* m) { msgs.erase(m); }
};

void swap(Folder&, Folder&);    // my code

file.cpp

void swap(Message& lhs, Message& rhs) {
  using std::swap;
  for (auto f : lhs.folders) { f->remMsg(&lhs); }
  // In vs2019 
  // Error (active) E0265   function "Folder::remMsg" is inaccessible
  // ...
}

如您所见,我无法使用方法Folder::remMsg()

然后我试着弄清楚 friend 函数是如何工作的。

struct B;  // This is [line 1]

struct A {
  friend void swap(A&, A&);

 private:
  int n;
  std::vector<B*> Bs;
};

void swap(A& lhs, A& rhs) {
  for (auto f : lhs.Bs) { f->n; }
  // f->n is still inaccessible
  // If I delete line 1, the code can be compiled successfully
  // same with class Folder
  // ...
}

struct B {
  friend struct A;

 private:
  int n;
  A C;
};

我不明白为什么会这样。

(我声明 class Messageclass Folder 朋友 class 是因为我希望对称 swap 使用复制交换)

void swap(Message& lhs, Message& rhs)Message 的好友,但您尝试访问 Folder 的私有成员。您的最后一个代码有同样的问题:friend void swap(A&, A&);A 的好友,但您尝试访问 B 的私有成员。 friend 不可传递。仅仅因为 AB 的朋友并且 swapA 的朋友并不意味着 swapB 的朋友。

如果你想 void swap(A&,A&) 授予 B 的私有成员访问权限,然后使其成为 B 的好友:

#include <vector>

struct B;

struct A {
  friend void swap(A&, A&);

 private:
  int n;
  std::vector<B*> Bs;
};

struct B {
  friend void swap(A&,A&);

 private:
  int n;
  A C;
};

void swap(A& lhs, A& rhs) {
  for (auto f : lhs.Bs) { f->n; }
                // ^^ access private member of A
                        //^^ access private member of B
}