【发布时间】: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 Message 和class Folder 相互声明为朋友类,因为我希望对称swap 使用复制交换)
【问题讨论】:
-
将
Folder声明为Message的friend意味着Folder的成员函数可以调用Message的成员函数private。函数swap()不是Message的成员或friend,因此无法访问Message的私有成员。 -
f->n尝试访问B的私有成员。友谊不是传递的;swap成为A的朋友,A成为B的朋友并不意味着swap是B的朋友。 (B实例恰好是“通过”A实例访问的,这无关紧要;可访问性不会“转移”。)
标签: c++ friend-function