Direct Question: With three (or more) nearly identical copies of a class object, how can I best (or most efficiently) store the differences between them?
Background: I have an algorithm which requires a set of parameters:
struct params
{
std::string A;
std::string B;
double C;
double D;
userDefinedTypeDef S;
};
And I want to call my algorithm three times. The first time, C = 3 & S = 'foo'. The second time, C = 4 & S = 'foo'. And the third time, C = 4 & S = 'bar'. Now the example given is merely for illustration, the true object is a class, not a structure, and has a few hundred members. I also want to call the algorithm many more than three times, so I don't want to have extra copies of this object running around. So what is the best pattern / implementation / method for storing only the difference between two class objects?
In other words, how can I store "Object 2 is the same as &(Object 1) except that C = 4"??
Edit: As noted in the comments below, I'd really like to avoid altering the function call as well as arrays of either the parameter class object or 开发者_Python百科the member objects. My purpose in doing so is to keep one copy, ala "currentParam" and then keep a list of the differences between successive calls. That way, I can simply update the values which changed, leaving all else fixed, and use the function given to me.
That said, what's the easiest way to do this? Create a class with boolean flags 'member1_changed'? And then use a union? I'm fairly stuck -- been puzzling a bit about sparse matrix storage and how that might be related -- hence why I asked the question.
You might find the Flyweight design pattern to be of interest. It is designed specifically to solve your problem.
Here's one way to store the differences:
Step 1: Replace all your members with pointers to the members. Yes, this adds a little memory overhead.
Step 2: Have classes store shallow copies of shared members instead of deep copies.
If your classes are not immutable, this technique becomes more complicated, though the basic idea is still doable.
Note that this does reduce memory footprint, but will also reduce spatial locality of memory references. This may slow down your program significantly. It also adds an extra layer of indirection.
A few hundred members? That sounds like bad design right from the get-go to me. I can't even think of an object I could describe that requires so many things. I can think of a system which does. But to be fair, I'm not criticizing you as I don't even know if you originally wrote this. I'd look at ways in which I could intelligently split the class into subclasses or even group the data into better representations. That's a first start.
After that I'd also look at perhaps rewriting your function so that it accepts just the parameters it's operating on:
void foo(Bar _objectWithTonsOfMembers){ //stuff...
into
void foo(int itemCount, double price, double discount, Customer customer){ //stuff
Once you have that done you can think about handling requests with different parameters. Boost::Bind combined with Boost::Function helps when dealing exactly with these types of situations:
boost::function<void(int,double)> refinedFoo = boost::bind(foo, _1, _2, 4.09, Customer("Pam"));
refinedFoo(1, 3.0);
refinedFoo(2, 2.0);
Now I can easily call the function I want only with the parameters which are changing.
Edit:
To clarify what I meant my "subclasses," I was not referring to inheritance but rather structure. Hence, I want you to take some class "Foo" and make it into a composition of classes Bar, Baz, Biff, and Bam. These should be broken down into logical elements as they are used within your code.
And by that I mean, if you have a function which operates only of 4 member variables and those members variables are in general always operated on in the same manner then that is a good place to create a new class or struct.
精彩评论