Home > Back-end >  Friend function cannot access private members
Friend function cannot access private members

Time:09-22

I do not speak much English, sorry. When I read c primer, I meet this code.

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

I have omitted functions that I think are irrelevant. Besides, c primer asks me to implement class Folder by myself. So I add more code.

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

In 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
  ...
}

As you can see, I can't use the function Folder::remMsg. Then, I try to figure out how friend function works. I write these codes.

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

I don't understand why does this happen. By the way, the reason I declare class Message and class Folder friend class with each other is I want symmetric swap to use copy-swap.

CodePudding user response:

void swap(Message& lhs, Message& rhs) is a friend of Message, but you try to access private members of Folder. Your last code has the same issue: friend void swap(A&, A&); is a friend of A but you try to access private members of B. friend is not transitive. Just because A is friend of B and swap is a friend of A does not mean swap is a friend of B.

If you want void swap(A&,A&) grant access to private member of B then make it a friend of 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
}
  •  Tags:  
  • c
  • Related