我有一个带有受保护方法Zig :: punt()的类,我只希望它可以被“Avocado”类访问。在C ++中,您通常会使用“朋友Avocado”说明符来执行此操作,但这会导致“Avocado”类可以访问所有其他变量;我不希望这样,因为这打破了封装。
我想要的是不可能的,还是已经存在一个我可以用来实现我想要的模糊技巧?或者可能会实现同样的替代类设计模式?
提前感谢任何想法!
答案 0 :(得分:4)
这是一个丑陋而又有效的技巧:
class AvocadoFriender {
protected:
virtual void punt() = 0;
friend class Avocado;
}
class Zig : public AvocadoFriender {
...
protected:
void punt();
}
基本上,您添加了一个mixin类,它只公开您想要Avocado的接口部分。我们利用这样一个事实:通过继承一个与Avocado成为朋友的类,除了最初暴露的内容之外,你不会暴露任何其他东西。
答案 1 :(得分:3)
我个人喜欢Key
模式。
class WannaBeFriend { /**/ };
class WannaBeFriendKey: boost::noncopyable
{
friend class WannaBeFriend;
WannaBeFriendKey () {}
};
现在:
class LimitedAccess
{
public:
Item& accessItem(const WannaBeFriendKey&) { return mItem; }
private:
Item mItem;
Item mOtherItem;
};
我真的很喜欢这个解决方案,因为:
WannaBeFriend
的子类:它只需要公开protected: static const WannaBeFriend& Key();
(可能适用也可能不适用)当然,编译器很可能会优化此引用的传递,因为它不会用于任何目的,因此它不会破坏设计,也不会添加不必要的临时值:)
答案 2 :(得分:0)
您可以将代理添加到Zig类
class Foo
{
private:
int m_x, m_y;
public:
class Bar
{
friend class Baz;
int& x(Foo& blubb)
{
return blubb.m_x;
}
};
friend class Bar;
};
class Baz
{
public:
void grml(Foo& f)
{
Foo::Bar b;
// Yes, this looks awful
b.x(f) = 42;
}
};
void z()
{
Foo f;
Baz b;
b.grml(f);
}