有几个类通常是由其他类派生的。它们是用户输入的接收器,例如按键接收器,键释放接收器,鼠标移动接收器等。从这些类继承的类有:例如,热键操作(它从按键按下接收器和键释放接收器继承),或照相机旋转器(从鼠标移动接收器继承)。用户所做的输入将由另一类转发到相应的接收器,因此是任何输入接收器,例如:相机旋转器需要在该转发类中进行注册。转发输入的类总是相同的,永远不会有两个。
当我的类(class)用户创建新的输入接收器时,该类会继承自鼠标移动接收器,鼠标移动接收器需要知道转发类,才能进行注册以接收鼠标输入。因此,鼠标移动接收器构造函数的代码如下所示:
mouseMoveReceiverIF(inputforwarder* ifo)
{
ifo.registerInputReceiver(this);
}
由于很明显只有一个inputforwarder,因此如果用户必须通过它不仅不那么直观,而且对于创建的每个输入接收器来说,这都是附加的输入。
但是,如果我将inputforwarder设为单例或全局变量,以便输入接收者可以访问它而无需用户在构造函数中传递它,那么我将遇到其他问题:然后用户需要知道在创建任何inputforwarder之前,inputforwarder必须存在。没有什么可以警告他,没有什么可以迫使他首先创建输入转发器。该程序将简单地崩溃,因为输入接收器将尝试向不存在的输入转发器进行注册。这将更加糟糕。
有效和适当的方式是什么样的?以上示例的替代方法是什么?
谢谢!
最佳答案
首先,我会问您是否应该向用户隐藏InputForwarder的实例。调用这些构造函数的用户代码正在配置系统并设置依赖关系-即使这意味着键入一个额外的构造函数参数,代码很可能应该明确声明那些依赖关系。
假设您要隐藏它,这取决于如何创建输入转发器:
万一您担心,可测试性在这里可能不是问题。即使您有一个全局“默认”实例来隐藏普通用户的依赖关系,您仍然可以拥有如下构造函数:
mouseMoveReceiverIF(inputforwarder* ifo = 0)
{
if (!ifo) {
ifo = getDefaultIfo();
// check for null again if necessary
}
ifo.registerInputReceiver(this);
}
因此,您可以注入(inject)适用于测试的任何inputforwarder。
关于c++ - 一遍又一遍地传递对象的替代方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15407046/