【问题标题】:Friend function cannot access private members好友功能无法访问私人会员
【发布时间】:2021-11-15 20:09:44
【问题描述】:

在阅读C++ Primer时,我遇到了以下sn-p(我已经省略了我认为不相关的代码):

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()

然后我试着弄清楚朋友功能是如何工作的。

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 相互声明为朋友类,因为我希望对称swap 使用复制交换)

【问题讨论】:

  • Folder声明为Messagefriend意味着Folder的成员函数可以调用Message的成员函数private。函数swap() 不是Message 的成员或friend,因此无法访问Message 的私有成员。
  • f-&gt;n 尝试访问 B 的私有成员。友谊不是传递的; swap 成为A 的朋友,A 成为B 的朋友并不意味着swapB 的朋友。 (B 实例恰好是“通过”A 实例访问的,这无关紧要;可访问性不会“转移”。)

标签: c++ friend-function


【解决方案1】:

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

如果您希望 void swap(A&amp;,A&amp;) 授予对 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
}

【讨论】:

  • 朋友不是及物的这句话很关键。谢谢。
猜你喜欢
  • 2021-01-02
  • 1970-01-01
  • 1970-01-01
  • 2021-08-05
  • 1970-01-01
  • 2016-11-02
相关资源
最近更新 更多