我需要有关如何解决下述问题类型的建议。我是C ++和OO-design的新手。
我已经学会了:
但是在创建引用其他对象的对象时,我们必须将这些引用作为输入参数传递给构造函数。因此,我们需要了解我们不应该知道的对象。
但请看以下示例:
假设我有一个对象“菜单”,需要拥有自己的计时器对象“计时器”。我想将此关联实现为参考。
对象 MenuHandler 汇总了很多菜单对象,但对 Timer 对象一无所知。但是当 MenuHandler 创建一个Menu对象时,它必须将 Timer 引用参数传递给构造函数。因此,**** MenuHandler **必须知道** Timer ****。
关于如何处理这类问题的任何建议?
答案 0 :(得分:4)
当谈到两个编号时,我会毫不犹豫地祝福你选择的单词。它们是你学习C ++的正确方式的标志,但它们可能会误导其他新手。当我看一下你的具体例子时,这就变得更加明显了。
MenuHandler 不应创建菜单。菜单的内容由应用程序确定,因此应用程序对象(或控制器部分,如果您已实现模型 - 视图 - 控制器)应创建菜单。 MenuHander 仅取得在其他位置创建的菜单的所有权。
此外,为每个菜单提供自己的计时器可能是有意义的。这意味着这种关系可以被描述为“有一个”;菜单有一个计时器。通常通过引用实现的关系可以被描述为“知道一个”(继承关系通常称为“是一个”)。如果每个Menu对象都有一个Timer,它可以是一个成员,并由Menu构造函数初始化。内部的Timer对象可以在其构造函数中获得对系统时钟的引用,但这不是您的担忧。
答案 1 :(得分:2)
为什么不简单地让Timer对象成为Menu类的成员(按值)?
答案 2 :(得分:1)
我发现我生成了更好(更易于维护,更快速等)的代码,而且我使用C ++中的引用比使用指针解决同样的问题更有效率...我认为对你的例子的传统答案将有一个创建菜单的工厂对象。通过这种方式,MenuHandler不需要知道Timer类。
答案 3 :(得分:1)
MenuHandler创建一个Timer对象,将其传递给Menu构造函数,并忘记它。这似乎完全合理。
如果MenuHandler不必要地保留对Timer的引用,那将违反建议点#2。
答案 4 :(得分:1)
在更一般的情况下,您需要为另一个类提供一个类以进行某种回调,您可以通过使用接口来避免相互依赖(彼此相互了解)。 A类派生自接口。 B类在构造函数中接受接口作为参数,并在需要时从该接口调用虚函数。 另请检查observer 设计模式。
答案 5 :(得分:1)
对于#1要非常小心对象的生命周期。参考文献不适用于处理objets的动态图形(如菜单,menuhandler,计时器等)。如果您想稍后更改计时器对象怎么办?
如果引用对象的生命周期尚未确定,那么在类中引用作为成员并不是一个好主意。
避免指针并不意味着在任何地方都使用引用,你应该看看更适合你想做的智能指针。