在C ++应用程序中,假设我有一个窗口类,它有几个控件类实例。如果我的窗口想要通知控件已被单击,我可能会使用:
control[n]->onClick();
现在让我们说控件需要知道它的父窗口的大小,或者其他一些信息。为此我正在考虑给控件一个指向自身(this)的指针作为它的构造函数的参数。然后,我将通过控件onClick()方法进行这样的调用:
Size windowsize = parent->getSize();
这会被视为不良做法,还是以任何其他方式与面向对象编程的价值相矛盾?如果是这样,他会采取什么样的“正确”方式呢?
作为一个附带问题,有一个Class或Class *的向量会更好吗?是否值得为速度增益增加复杂性? (向量的变化很少见。)
答案 0 :(得分:11)
您可以将控件层次结构视为树状图形数据结构;当你以这种方式可视化时,控件有一个指向其父级的指针是非常合理的。
至于是否应将对象或指向对象的指针存储在向量中,这取决于它。您通常应该更喜欢存储对象,但有很多时候您不能这样做,或者这样做是不切实际的。例如,如果您需要利用多态性并存储所有派生自公共基类的不同类型的事物,则需要使用指针。
如果你存储指针,请确保使用某种智能指针或指针容器;否则,异常安全就是一种殴打。
答案 1 :(得分:8)
没关系。这是UI框架中的常见模式。例如,.NET Windows Forms Control
类有一个用于指定父(http://msdn.microsoft.com/en-us/library/wawy06xc.aspx)的构造函数。
答案 2 :(得分:5)
事实上,GOF复合设计模式基于显式父引用。
显式父引用。 保持孩子的参考 他们父母的组件可以 简化遍历和管理 复合结构父母 参考简化了向上移动 结构和删除组件。 父参考也有助于支持 责任链(223) 模式。通常定义的地方 父引用位于Component中 类。 Leaf和Composite类可以 继承引用和 管理它的操作。
使用父引用,这是必不可少的 保持所有的不变量 复合材料的孩子有他们的 父母反过来拥有的复合体 他们是孩子。最简单的方法 确保这是为了更改组件 父母只有在被添加或者被添加时 从复合材料中删除。如果可以的话 在Add和中实现一次 删除Composite的操作 类,然后它可以被所有人继承 子类和不变量 自动维护。
因此,我想,根据实际需求和背景,这样的设计有一个明确的位置。
答案 3 :(得分:4)
不,这完全没问题。唯一的问题是它增加了实例之间的耦合程度。此外,如果您考虑使用上面建议的智能指针,请确保您引用父“弱”。假设您的窗口树不是太深,您可以考虑从已知的顶部窗口开始确定父dyuamica1ly。
答案 4 :(得分:2)
没关系。但是,请确保您需要它,因为它可能会在子级父级可以更改的情况下使代码复杂化。检查为什么孩子需要知道其父母是谁,并考虑成本和替代方案。您的场景的一个示例替代方案是:调整父级窗口大小时,调整大小可以自上而下,它可以通过迭代和调用方法或设置属性来告诉其子级调整大小。当一个孩子需要调整大小时(比如可以根据其中的数据增长的文本框),它可以向任何听到的人说出它调整大小并且父母可以监听该事件的事件。
答案 5 :(得分:1)
如果您需要这样做,请考虑将父级传递为const*
。
答案 6 :(得分:0)
这还不错。例如,在Qt小部件中,即使不使用const*
,每个小部件也会有指向父级的指针。