在以下情况中,友谊是否有其他选择?
我有一个代表UI窗口的Window
类。此外,作为单例实现的WindowManager
类管理应用程序中的所有窗口对象(呈现UI,调度事件等)。
WindowManager
将具有一个公共接口,该接口仅包含其单例实例化方法和用于呈现UI和分派UI事件的函数。
我还希望Window
个对象在构造期间注册WindowManager
并在销毁期间取消注册。 WindowManager::register
和WindowManager::deregister
方法将是私有或受保护的,因为我不希望客户端(Window
个对象除外)能够使用此接口。
在这种情况下,是否有一种方法可以避免Window
和WindowManager
之间的友谊?也许是一种完全不同的方式来实现类似的结果?
答案 0 :(得分:4)
是的,但友谊是最好的解决方案,因为它专为这种情况而设计。
另一种方法是让Window
成为WindowManager
的成员(注意,这需要新的C ++ 11辅助功能规则)。或者它来自WindowManager
的成员。或者它来自WindowManager
本身。
您还可以在Window
中放置一个私有类型,使Window
中嵌套的密钥类型只能从该私有类型构造,并且需要将该密钥类型的实例传递给{{ 1}}。这应该适用于C ++ 11之前的编译器。
当然,任何方法都可以使用足够的投射来绕过。
答案 1 :(得分:2)
在这里使用Friend
似乎是合适的。您想在两个类之间指出故意强耦合,这可以通过朋友恰当地表明。
更具体地说,一个类需要访问另一个类的内部,并且您不希望使用公共访问说明符授予每个人访问权限。
经验法则:公众太弱,私人太强,你需要某种形式的选择访问:受保护或朋友。
使用Friend
发货是这里的最佳解决方案。
答案 2 :(得分:2)
使用嵌套类。
WindowManager {
private:
static void construct();
static void destruct();
public:
class InternalWindow { // can access WindowManager's private members (no scoping needed)
InternalWindow() { construct(); }
~InternalWindow() { desstruct(); }
};
};
typedef WindowManager::InternalWindow Window; // to make scoping easier
答案 3 :(得分:2)
另一个解决方案(不一定更好:])是将窗口注册放到a separate component
- 让我们说WindowRegister。 WindowRegister可以有一个公共接口进行注册,也可以是WindowManager的私有成员。
problem with friendship is that it is not inherited
(我的爷爷的朋友不需要我的朋友) - 并且Window或WindowManger很可能是多态的。
此致
答案 4 :(得分:1)
还有其他几种选择。例如:
或者你可以让他们成为朋友。这比任何其他选项更容易和更安全,以及为什么朋友存在。