CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    May 2009
    Posts
    103

    Call a function in a higher level class?

    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.

    Any suggestions?

  2. #2
    Join Date
    Nov 2006
    Posts
    1,611

    Re: Call a function in a higher level class?

    Some code or pseudo code would be useful here.

    I'll try to surmise.

    Code:
    class Acct
    {
     AcctTabs * m_tbctrl;
    };
    
    class AcctTabs
    {
     AcctList * tabAcctList;
    };
    
    class AcctList
    {
     Acct * acct;
    
     void func()
       {
         acct->UpdateNames();
       }
    };
    AcctList is a child of a child which needs to 'know' the parent of it's parent in order to make the call.

    AcctList must therefore obtain a pointer to the appropriate instance of Acct, by whatever initialization path can be fashioned.

    There must be some point where the m_tbctrl is set to the appropriate child. At that point, AcctTabs should probably obtain a pointer to it's parent.

    Likewise, there must be some point where tabAcctList is set to it's child, and at that point the AcctList could receive it's parent.


    Code:
    class Acct
    {
     AcctTabs * m_tbctrl;
    };
    
    class AcctTabs
    {
     Acct *parent;
     AcctList * tabAcctList;
    };
    
    class AcctList
    {
     AcctTabs *parent;
     Acct * acct;
    
     void func()
       {
         parent->parent->UpdateNames();
       }
    };
    Obviously this parent to parent is uncomfortable, but workable, so at the point where AcctList sets it's AcctTabs * parent, it could also obtain acct...

    acct = parent->parent;
    Last edited by JVene; July 26th, 2009 at 02:59 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).

  3. #3
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: Call a function in a higher level class?

    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:

    Code:
    class CMainFrame {
      . . .
        Acct* m_pacct;
        afx_msg LRESULT OnUpdateNames(WPARAM wp, LPARAM lp) { 
             if (m_pacct)
                  m_pacct->UpdateNames();
       }
    };
    
    class AcctList {
      . . .
       void func() {
         AfxGetMainWnd()->PostMessage(WM_ACCT_UPDATENAMES);
       }
    };
    Last edited by Igor Vartanov; July 27th, 2009 at 02:06 AM.
    Best regards,
    Igor

  4. #4
    Join Date
    May 2009
    Posts
    103

    Re: Call a function in a higher level class?

    Thanks for the fast reply.... I was wondering, could this somehow be done with a global definition for the acct that then could be called elsewhere in any class?

  5. #5
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: Call a function in a higher level class?

    Yes, why not. I wouldn't say global object is the best approach, but this will work.
    Best regards,
    Igor

  6. #6
    Join Date
    Nov 2006
    Posts
    1,611

    Re: Call a function in a higher level class?

    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).

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured