views:

252

answers:

5

In a C++ application, let's say I have a window class, which has several instances of a control class. If my window wanted to notify a control that it had been clicked, I might use:

control[n]->onClick();

Now let's say that the control needs to know the size of it's parent window, or some other information. For this I was considering giving the control a pointer to itself (this) as a parameter to it's constructor. I would then make a call like this from the controls onClick() method:

Size windowsize = parent->getSize();

Would this be considered bad practice, or in any other way contradict the values of object orientated programming? If so, what would he the 'proper' way of doing this?

As a side question, would it be better to have a vector of Class or Class*? Is it worth the added complexity for the speed gain? (Changes to the vector would be infrequent).

+5  A: 

That's fine. It's a common pattern in UI frameworks. E.g., the .NET Windows Forms Control class has a constructor for specifying the parent (http://msdn.microsoft.com/en-us/library/wawy06xc.aspx).

Mark Cidade
+6  A: 

You can consider a hierarchy of controls as being a tree-like graph data structure; when you visualize it that way, it's quite reasonable for a control to have a pointer to its parent.

As for whether objects or pointers to objects should be stored in a vector, well, it depends. You should usually prefer to store objects, but there are a lot of times that you can't do so or it's impractical to do so. For example, if you need to take advantage of polymorphism and store different types of things all derived from a common base class, you'll need to use pointers.

If you do store pointers, make sure to either use a smart pointer of some kind or a pointer container; otherwise, exception safety is a beating.

James McNellis
+2  A: 

In fact the GOF Composite design pattern is based on Explicit Parent References.

Explicit parent references. Maintaining references from child components to their parent can simplify the traversal and management of a composite structure. The parent reference simplifies moving up the structure and deleting a component. Parent references also help support the Chain of Responsibility (223) pattern. The usual place to define the parent reference is in the Component class. Leaf and Composite classes can inherit the reference and the operations that manage it.

With parent references, it's essential to maintain the invariant that all children of a composite have as their parent the composite that in turn has them as children. The easiest way to ensure this is to change a component's parent only when it's being added or removed from a composite. If this can be implemented once in the Add and Remove operations of the Composite class, then it can be inherited by all the subclasses, and the invariant will be maintained automatically.

Therefore, I guess, there is a clear place for such a design, depending on the actual requirement and context.

Chubsdad
+1  A: 

No, it's completely fine. The only issue is that it increases the level of coupling between instances. Also, if you consider usage of smart pointers as advised above, be sure that you make the reference to parent 'weak'. Assuming your window trees are not too deep, you could consider to determine the parent dyuamica1ly, starting from a known top window.

paul_71
A: 

It is OK. However, make sure you need it because it can complicate your code in situations where a childs parent can change. Examine why the child needs to know who its parent is and consider the costs and alternatives. An example alternative for your scenario would be: Resizing can come from the top down when a parents window is resized it can tell its children to resize by iterating and calling a method or setting a property. When a child needs to resize (like a textbox that can grow based on the data in it) it can raise an event to anyone listening saying that it resized and the parent could listen for that event.

BitOff