我有一个带有受保护方法 Zig::punt() 的类,我只希望“鳄梨”类可以访问它。在 C++ 中,您通常会使用“friend Avocado”说明符来执行此操作,但这会导致“Avocado”类可以访问所有其他变量;我不想要这个,因为这会破坏封装。
我想要什么是不可能的,还是已经存在一个晦涩难懂的技巧可以用来实现我想要的?或者可能实现相同目的的替代类设计模式?
提前感谢您的任何想法!
我有一个带有受保护方法 Zig::punt() 的类,我只希望“鳄梨”类可以访问它。在 C++ 中,您通常会使用“friend Avocado”说明符来执行此操作,但这会导致“Avocado”类可以访问所有其他变量;我不想要这个,因为这会破坏封装。
我想要什么是不可能的,还是已经存在一个晦涩难懂的技巧可以用来实现我想要的?或者可能实现相同目的的替代类设计模式?
提前感谢您的任何想法!
这是一个丑陋但有效的技巧:
class AvocadoFriender {
protected:
virtual void punt() = 0;
friend class Avocado;
}
class Zig : public AvocadoFriender {
...
protected:
void punt();
}
基本上,您添加了一个 mixin 类,该类仅公开您想要 Avocado 的部分接口。我们利用了这样一个事实,即通过继承一个与 Avocado 友好的类,除了最初暴露的内容之外,您不会再暴露任何东西。
我个人喜欢这种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
:它只需要公开 a protected: static const WannaBeFriend& Key();
(可能适用,也可能不适用)当然,编译器很可能会优化此引用的传递,因为它没有任何用途,因此它不会破坏设计,也不会添加不必要的临时性:)
您可以向 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);
}