class B;
class A {
protected:
int x;
private:
int y;
};
class A_wrapper : public A {
friend B;
};
class B {
public:
A_wrapper a;
int foo() {
a.x; // Ok
a.y; // Compiler error!
}
};
protected
仅适用于基类子对象的成员,而不适用于同类型的其他对象的成员。(即只能通过 this
) - MSalters很久以前,在这个网站上,我提出了一个使用 Key
的方案。这个想法是,主类记录哪些接口可以公开访问,哪些需要密钥,并授予需要它的人密钥的友好权限。
class Key { friend class Stranger; Key() {} ~Key() {} };
class Item {
public:
void everyone();
void restricted(Key);
private:
};
现在,只有Stranger
可以使用restricted
方法,如下所示:
class Stranger {
public:
void test(Item& i) {
Key k;
i.restricted(k);
}
Key key() { return Key(); }
Key _key;
};
class Other {
void test(Item& i) {
Stranger s;
i.restricted(s.key()); // error: ‘Key::~Key()’ is private
// error: within this context
}
void test2(Item& i) {
Stranger s;
i.restricted(s._key); // error: ‘Key::~Key()’ is private
// error: within this context
// error: initializing argument 1 of ‘void Item::restricted(Key)’
}
};
这是一个非常简单的方案,它允许比完全的友谊更细致的方法。
该内容涉及IT技术。Oli提供了一个更接近的解决方案(+1),但你也可以使用选择性好友的方法来处理:
#include <iostream>
class t_thing;
class t_elsewhere {
public:
void print(const t_thing& thing);
};
class t_thing {
public:
class t_selective_friend {
static int Prot(const t_thing& thing) {
return thing.prot;
}
friend class t_elsewhere;
};
public:
int publ;
protected:
int prot;
protected:
int priv;
};
void t_elsewhere::print(const t_thing& thing) {
std::cout << t_thing::t_selective_friend::Prot(thing) << std::endl;
}
int main() {
t_thing thing;
thing.publ; /* << ok */
thing.prot; /* << error */
thing.priv; /* << error */
t_elsewhere().print(thing); /* << ok */
return 0;
}
有时候冗长和控制是好的...