友元函数无法访问私有成员
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 Message
和 class Folder
朋友 class 是因为我希望对称 swap
使用复制交换)
void swap(Message& lhs, Message& rhs)
是 Message
的好友,但您尝试访问 Folder
的私有成员。您的最后一个代码有同样的问题:friend void swap(A&, A&);
是 A
的好友,但您尝试访问 B
的私有成员。 friend
不可传递。仅仅因为 A
是 B
的朋友并且 swap
是 A
的朋友并不意味着 swap
是 B
的朋友。
如果你想 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
}
在阅读 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 Message
和 class Folder
朋友 class 是因为我希望对称 swap
使用复制交换)
void swap(Message& lhs, Message& rhs)
是 Message
的好友,但您尝试访问 Folder
的私有成员。您的最后一个代码有同样的问题:friend void swap(A&, A&);
是 A
的好友,但您尝试访问 B
的私有成员。 friend
不可传递。仅仅因为 A
是 B
的朋友并且 swap
是 A
的朋友并不意味着 swap
是 B
的朋友。
如果你想 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
}