18

When modelling an object with children it's common to include the children via composition, as a member of the parent class. Sometimes however the children need to tell the parent something, they need to call a function of the parent. How can this be accomplished using C++? Some options are:

  1. Make the parent class global therefore the child objects will be able to call member functions of the parent object.

  2. Inject the parent object as a, pointer or reference, into every child object. Then when the child needs to tell the parent object something, it can always do so because it has a member variable that it can use.

What are other methods of doing this? Is there a general design pattern or name for this sort of thing?

Note that I'm interested in ideas and solutions in C++ because the details are going to be different in other object-oriented languages. For example point 2 above mentions 'pointers or references' and both are only possible in C++. C++ has language features that are not present in other languages therefore implementations of a solution to the problem will potentially incorporate these language features making the solution different from what someone might come up with in another language.

4
  • can you add an example? Is this a valid example for your question? You have an orderobject (=parent) with orderitems (children) and want to update the order total when an orderitem-quantity is changed? or are thinking of something completely different?
    – k3b
    Commented May 22, 2012 at 13:18
  • @k3b Yeah that's a valid example. Some information in the child has changed requiring the parent to do something.
    – sashang
    Commented May 22, 2012 at 13:23
  • just add some constructor parameters and reference data members to each child class.
    – tp1
    Commented May 22, 2012 at 23:00
  • Does the child need to know all about the parent, or would a simple delegate be sufficient? Commented Sep 14, 2013 at 12:48

7 Answers 7

17

First things first, this can be a code smell. The point of using composition for the parent/children is that the parent knows about the children but not vice versa. Especially if the relation is more of a 'contains' than 'is composed of'.

A reference to the parent is possible and fairly common in C++. In other languages, a function object or event is more often used to allow the child to communicate things that outsiders might want to know. This is a common publish-subscriber sort of pattern. I suspect that which is more idiomatic depends on which version of C++ you're using and the standards of your codebase.

2
  • In my situation it's a code smell. Great answer. Commented Jun 4, 2017 at 10:37
  • I love this answer. I wish people would keep this in mind when learning React/Redux (2 massive violators of comp sci principles, I believe). Just adding this so future devs who only know JS step back and say "Maybe I should think about my architecture more"
    – Stephen J
    Commented Apr 18, 2020 at 19:05
6

As others have pointed out, the basic idea of injecting the parent object as a pointer or reference is the way to go - in principle.

This has one drawback: you get a cyclic dependency between the parent and the child. If you want to avoid that, define an abstract base class (an interface) IParent from which your parent inherits. IParent should contain the methods as virtual functions the child wants to call. Then, inject the parent as a reference to IParent. This makes unit testing the child a lot easier, since now you can replace the parent object easily by a mock object.

If your child needs to call just one function of your parent object, a complete IParent class may be oversized. In this case, it will be enough to inject a pointer to the member function into the child, or a functor object encapsulating that member function.

2

What you can do is keep a reference to the parent in the child class, by composition. That way, the child knows his parent and can invoke public methods on it.

So I would go with option 2. You have to be careful though, when a child is removed from the parent, you need to remove the reference to the parent in the child and point it to null (or a new parent, if he has one). Or you could simply delete the child object, depending on the context.

1

Pass them a reference or a pointer to the parent. You can make them friends of the parent, or make the called method public. If you don't want to do any of the above, you can pass them a "bridge" object which exposes one of the parent's methods as public and is itself a prive nested class of the parent (therefore it has access to every parent method). This can be a bit too complex in many situations, however.

1

2) Inject the parent object as a, pointer or reference, into every child object. Then when the child needs to tell the parent object something, it can always do so because it has a member variable that it can use.

Is a perfectly viable option. All modern languages have a feature which can be used to refer to another language.

1

There is a similar approach with slight variation but which gives advantages:

Say Parent A contains Component C.

In Component C, declare InterfaceC and hold reference to it. This is the interface of the component with the outside world.

Parent A implements InterfaceC, and sets its reference in Component C. Component C sees Parent A as InterfaceC.

The idea is: A component talks to the outside using its interface.

The advantages of using this over setting the parent directly is:

Say the component does something and it needs to notify the parent. It calls the interface. Later, you decide you want to change the parent. The component doesn't care at all and you won't do any changes in it.

Say later you want to notify many objects of an event. You simply create a list of InterfaceC and add references to it.

Disadvantages: A parent class will end up implementing many interfaces (I think of this as an advantage though, since by looking at the class declaration, I immediately know who talks to it)

0

Note this is c# specific. I donot know if c++ has something similar.

If you have a gui-form with pushbuttons you usually have an a different approach using Event-Subscribtion also known as Observer_pattern or Publish–subscribe pattern.

The pushbutton usally does not know the specific form where it lives. Instead the button triggers or publishes an event and the form receives a subscribed notification and can react accordingly.

Beside gui-s this mechanism can be used in every paren-child-relation

Not the answer you're looking for? Browse other questions tagged or ask your own question.