Keeping one data structure through multiple classes.

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • kardon33
    New Member
    • May 2007
    • 158

    Keeping one data structure through multiple classes.

    I might be going at this wrong but here goes. I have a program with multiple classes, each of which I initialize in main.cpp

    I have a data structure that keeps track of the parameters for the program, defined in a file called Defines.h. All classes include this file.

    My structure is similar to this.
    Code:
    struct params {
      int paramone;
      float paramtwo;
    };
    In main I create a pointer to a params object like:
    Code:
    params* pointerToParams;
    This all works fine so far. What I want to happen is have this pointerToParams available to all my other classes and where ever it needs it in those classes.

    I first thing i did was in each classes initialize function it took a pointer to params as a parameter. This works. Then I made it that each class also has a private pointer variable of prams which I set equal to the passed param pointer.

    My problem is when I want to change a variable in the params structure in any class I want the changes to be reflected in all classes. So in short I only want one instance of params to be available anywhere in the program.

    Any thoughts,
    Thanks for the help.
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    You could create a Singleton object that is accessible from all of your other classes. This is, in effect a global object. Read the article in the C/C++ Insights for the Singleton Design Pattern.

    If you are required to notify other objects when the params change, then you need an Observer Design Pattern implementation. Basically, an object registers with another object as an observer. Then when notified object changes, it notifies the observer. If there are many observers you may need a Mediator object to notify multiple obserevers. The observer objects register witht eh Mediator. The Mediator watches for change in the target object.

    Once an object is notified that a target has changed, the target object can be accessed to determine what the change was. Usually, the changed data is not passed around but only the fact that a change occurred is passed.

    This is a common problem. For example, when your address changes, the mailing list, order database, department of motor vehicles, etc.. need to know about that.

    Get a copy of Design Patterns by Erich Gamma, et. al. though I expect a little Google will bury you in info.

    Comment

    • hype261
      New Member
      • Apr 2010
      • 207

      #3
      Good design pattern website

      Even though I have the gang of 4 designs pattern book sometimes I use the website listed below look up design patterns if I don't have the book close by. It is comparable to the book and gives code examples in other languages besides C++ and Small Talk.

      Design Patterns and Refactoring articles and guides. Design Patterns video tutorials for newbies. Simple descriptions and full source code examples in Java, C++, C#, PHP and Delphi.

      Comment

      • kardon33
        New Member
        • May 2007
        • 158

        #4
        Thanks for the great suggestions, the web site looks really helpful. However I ended up going with a more crude or dirty approach that fits my needs.

        Since all modules (each has a class) of my system that stem out from the main class and all have just one function that my main class calls in every time the program loops. I send a pointer of my argument structure in each one of the modules loop function. They then copy it locally, do what they need to do, then copy back their changes to the main classes.

        Its gonna work for my current design, definitely not the cleanest approach though.

        Comment

        • Banfa
          Recognized Expert Expert
          • Feb 2006
          • 9067

          #5
          Erm, does this program work in more than one thread of execution? (i.e. is it multi-threaded or multi-process or multi-tasked?)

          Comment

          • kardon33
            New Member
            • May 2007
            • 158

            #6
            No, it is not designed to. Well for the most part, there is a bit of code that I run multithread so it doesnt hold up the rest of the program. But that portion of the code is not dependent on any program data that im trying to keep track of.

            Would my current design fail if I were to add multi-thread schema to it. I think I see why it would.

            Comment

            • Banfa
              Recognized Expert Expert
              • Feb 2006
              • 9067

              #7
              Well within each loop function you "copy it locally, do what they need to do, then copy back their changes to the main classes".

              If that were multi threaded then presumably the loop functions would be running at the same time and that leaves the possibility of taking a copy in one loop while another loop is writing it back. Any time a multi-thread program allows the possibility of more than one access to a piece of data where at least one access is a write the possibility exists that you will get data corruption which rarely leads to a good end.

              Comment

              • emibt08
                New Member
                • Oct 2008
                • 25

                #8
                You could of course make a base class which takes your struct (possibly in the constructor) and derive all other classes that use it from that base class.
                The base class would have the struct as a protected member (or private with accessor functions), and you may put there all of your common functions declared as virtual if something in the derived classes needs to be done differently. Eg:

                Code:
                class Base
                {
                	Base(params* par) : params_(par) {}
                	virtual ~Base() {}
                	
                protected:
                	params* params_;
                };
                
                class Derived : public Base
                {
                	Derived(params* par) : Base(par) {}
                	void useParams() { /* use params_ */ }
                }

                Then, if you access it with multiple threads, as mentioned, you could do it this way:

                Code:
                class Base
                {
                	Base(params* par) : params_(par) {}
                	
                	params Params()
                	{
                		lock();
                		params p = *params_;
                		unlock();
                		return p;
                	}
                	
                	void setParams(params* par)
                	{
                		lock();
                		params_ = par;
                		unlock();
                	}
                	
                	void lock();
                	void unlock();
                	
                private:
                	params* params_;
                };
                where lock/unlock use some locking mechanism, depending on the OS that you're targeting, but possibly a mutex, or R/W lock (CRITICAL_SECTI ON would be a good choice for Windows)

                Comment

                Working...