This is just about as confusing to explain as to figure out... but, maybe it isn't as hard to do as I am beginning to think it is....
We have a class called Acct. In this class there is a function called UpdateNames. This account calls another class called AcctTabs by assigning an public variable within this class called m_tbctrl
The AcctTabs is a CTabctrl derived class. In this class, several tabs are defined and the appropriate classes called to display their dialogs on the appropriate tabs. One of the tabs is calling a class AcctList by assigning a public variable within this class called tabAcctList
The AcctList is a standard CDialog derived class. There is a function within this class that does some internal updating. When this function is fired, I need to call the UpdateNames function in the Acct class.
Every way I try to call it, I get compile errors. I am not an expert at C++ but pretty knowledgeable. Also, this is VC++ v6 if that matters.
The sample above describes a case of tight coupling when every object is obliged to know its parent. But the problem can be alternatively solved by sending a signal to some object which has the target object in its scope. This way the sender delegates this calling to some proxy object, like main frame object in the snippet below:
Igor Vartanov's point about tight coupling is classic and profound.
A global object is a move in the exact opposite direction, though you can use such a means to 'get by'.
Here's the thinking. When objects are tightly coupled there are several consequences. Among them, the objects can't be separated and used elsewhere. There are times when you can't use an object in isolation, but it's more common that you could. Another consequence is compilation - the interdependency usually means more code must be compiled if anything is edited. On a 'local' scale, and in small applications, this may not be obvious or significant. As a habit, however, it can lead to increased compilation time and reduced productivity in more ambitious work.
If a global value is used, there can only be one. So, what if you wanted to have a multiple window interface? What if it could be useful for multiple dialogs on display? The goal would be impossible unless everything used to drive the interface can be operated in duplicate (or triplicate, etc).
Objects are used as metaphors, they model concepts. If the concept being modeled involves an intimate interdependency, then it's entirely appropriate. A quick example, links in a list must have pointers to each other, but of course, these are objects of the same class. The container which "owns" them must have the ability to operate upon them, sometimes directly. The list container is not a container unless it has links, and although links ought to be owned by a container, it isn't necessarily a list container that must own them. These concepts suggest the kinds of interdependency we'd find reasonable in the objects representing them.
It may be, and I see this often, that a child/parent relationship is firm to the extent that it's unbreakable, and as such a set of child/parent pointers is appropriate for inter-object communication. If there's any chance the child might be 'lifted' out of that context and made to operate independently (as is also a common advantage), then it's important to keep them "untangled" from each other.
A message based paradigm does still involve a parental relationship, by whatever means a message is transacted (a window handle, a window pointer, etc), but is looser than a chain of child/parent pairs. There are command pattern designs where objects exchange anonymous "handles" and expose through them interfaces for inter-object communication. This paradigm is loose coupling in that the design requires the inter-object relationship to be conditional at runtime (it may connect and release, and ANY objects might be involved).
Boost offers some building blocks for that, QT has some of it built in - perhaps it's beyond this scope, and there are times when intermediate developers need to simply get done and move on (which usually require less than ideal solutions be accepted) - so I'll leave the rest as research for you.
Last edited by JVene; July 26th, 2009 at 05:57 PM.
If my post was interesting or helpful, perhaps you would consider clicking the 'rate this post' to let me know (middle icon of the group in the upper right of the post).