Pattern to share data between objects in C++

three logical steps, represented by three different classes

This may not have been the best approach.

A single class can have a large number of "global" variables, shared by all methods of the class.

What I've done when converting old codes (C or Fortran) to new OO structures is to try to create a single class which represents a more complete "thing".

In some case, well-structured FORTRAN would use "Named COMMON Blocks" to cluster things into meaningful groups. This is a hint as to what the "thing" really was.

Also, FORTRAN will have lots of parallel arrays which aren't really separate things, they're separate attributes of a common thing.

DOUBLE X(200)
DOUBLE Y(200)

Is really a small class with two attributes that you would put into a collection.

Finally, you can easily create large classes with nothing but data, separate from the the class that contains the functions that do the work. This is kind of creepy, but it allows you to finesse the common issue by translating a COMMON block into a class and simply passing an instance of that class to every function that uses the COMMON.


Why not passing the invariants as a function parameter or to the constructor of the class having the calculateFactor method ?

Also try to gather parameters together if you have too many params for a single function (for instance, instead of (x, y, z) pass a 3D point, you have then only 1 parameter instead of 3).


Well, in C++ the most suitable solution, given your constraints and conditions, is represented by pointers. Many developers told you to use boost::shared_ptr. Well it is not necessary, although it provides a better performance especially when considering portability and robustness to system faults.

It is not necessary for you to bind to boost. It is true that they are not compiled and that now standardization processes will lead to c++ with boost directly integrated as a standard library, but if you do not want to use an external library you obviously can.

So let's go and try to solve your problem using just C++ and what it provides actually.

You'll probably have a main method and there, you told before, initialize all invariants elements... so you basically have constants and they can be every possible type. no need to make them constant if you want, however, in main you instantiate your invariant elements and point them for all those components requiring their usage. First in a separate file called "common_components.hpp" consider the following (I assume that you need some types for your invariant variables):

typedef struct {
   Type1 invariant_var1;
   Type2 invariant_var2;
   ...
   TypeN invariant_varN;
} InvariantType; // Contains the variables I need, it is a type, instantiating it will generate a set of global variables.
typedef InvariantType* InvariantPtr; // Will point to a set of invariants

In your "main.cpp" file you'll have:

#include "common_components.hpp"
// Functions declaration
int main(int, char**);
MyType1 CalculateValues1(InvariantPtr); /* Your functions have as imput param the pointer to globals */
MyType2 CalculateValues2(InvariantPtr); /* Your functions have as imput param the pointer to globals */
...
MyType3 CalculateValuesN(InvariantPtr); /* Your functions have as imput param the pointer to globals */
// Main implementation
int main(int argc, char** argv) {
   InvariantType invariants = {
      value1,
      value2,
      ...
      valueN
   }; // Instantiating all invariants I need.
   InvariantPtr global = &invariants;
   // Now I have my variable global being a pointer to global.
   // Here I have to call the functions
   CalculateValue1(global);
   CalculateValue2(global);
   ...
   CalculateValueN(global);
}

If you have functions returning or using the global variable use the pointer to the struct modifying you methods' interface. By doing so all changes will be flooded to all using thoss variables.


There is a very simple template class to share data between objects in C++ and it is called shared_ptr. It is in the new STL and in boost.

If two objects both have a shared_ptr to the same object they get shared access to whatever data it holds.

In your particular case you probably don't want this but want a simple class that holds the data.

class FactorCalculator
{
   InvariantsType invA;
   InvariantsType invB;

public:
   FactorCalculator() // calculate the invariants once per calculator
   {
      invA.CalculateValues();
      invB.CalculateValues();
   }

   // call multiple times with different values of x, y, z
   double calculateFactor( double x, double y, double z ) /*const*/ 
   {
       // calculate using pre-calculated values in invA and invB
   }
};