Andreas
Andreas

Reputation: 7248

Keep track changes in c++ class

Will explain this with a simple example.

class Vector
{
    float X;
    float Y;
    float _length;
    float Length();
}

I only what to calculate Length and assign it to _length if X or Y changed. If none of them changed I just simply return _length.

Upvotes: 1

Views: 1268

Answers (7)

Chris Drew
Chris Drew

Reputation: 15334

An alternative to maintaining guard flags or "invalid" values as suggested by Jeff would be to use nullable objects such as pointers, preferably smart pointers. This may be more appropriate when the cache is an object larger than a float.

class Vector {
  float X;
  float Y;
  mutable std::unique_ptr<float> length_;

 public:
  Vector() : X(0.0f), Y(0.0f) { }
  Vector(float x, float y) : X(x), Y(y) { }

  float x() const { return X; }
  float y() const { return Y; }

  float length() const {
    if (!length_)
      length_ = std::unique_ptr<float>(new float(sqrt(X*X + Y*Y)));
    return *length_;
  }

  void setX(float x) { if (X != x) { length_.reset(); X = x; } }
  void setY(float y) { if (Y != y) { length_.reset(); Y = y; } }
};

Upvotes: 0

Jeff
Jeff

Reputation: 3525

You'll need to include a guard flag (or "invalid" value) that you flag with X/Y modifications through:

class Vector {
 public:
  Vector(float x = 0.0, float y = 0.0)
  : X{x}, Y{y}, Length{-1.0f}
  { }

  float x() const { return X; }
  float y() const { return Y; }

  float length() const {
    if (Length < 0.0f) {
      Length = sqrt(X*X + Y*Y);
    }
    return Length;
  }

  void setX(float x) { if (X != x) { Length = -1.0f; } X = x; }
  void setY(float y) { if (Y != y) { Length = -1.0f; } Y = y; }

 private:
  float X;
  float Y;
  mutable float Length;
};

The mutable qualifier means those values are not part of the "logical" state of an object and can be modified even on a const instance of Vector (via const member functions, naturally).

Upvotes: 5

Zaiborg
Zaiborg

Reputation: 2522

first thing that came to mind:

class Vector
{
public:
    void setX(float x)   {changed = true; X = x;}
    void setY(float y)   {changed = true; Y = y;}

    float length()
    {
        if (changed)
            // calculate

        changed = false;
        return _Length;
    }
private:
    floate X, Y, _Length;
    bool changed;
};

edit: i hope now the formating works ...

Upvotes: 0

S&#233;bastien Garmier
S&#233;bastien Garmier

Reputation: 1263

Make x and y private and add two functions like

void setX(float x) {
    this -> x = x;
    handleLengthChange();
}

and

void setY(float y) {
     this -> y = y;
     handleLengthChange();
}

The function handleLengthChange calculates the new length. Every class that uses Vector will now use the methods above to change x or y. Since x and y are private, just add two functions to get the values of x and y.

Upvotes: 1

Dimitrios Bouzas
Dimitrios Bouzas

Reputation: 42929

Easy, calculate length on the fly from variables X and Y. This way you'll get always the right length, no matter if X or Y has changed or not.

float Vector::Length()const
{
  return sqrt(X * X + Y * Y);
}

Upvotes: 0

bolov
bolov

Reputation: 75815

make X and Y accessible only through setters and getters. Have a boolean value that tells you if _length is up to date. On X and Y setters invalidate _length (via that boolean variable). When getting the length check if _length if valid. If yes just return it. If not compute it, make it valid and return it.

Upvotes: 0

Moha the almighty camel
Moha the almighty camel

Reputation: 4463

make your float X, Y; private and add a bool changed; to your class as well. changing X, Y will be done through setters functions that will also set the bool changed to false.

whenever you call the function Length(); it checks for the bool changed variable, if false then recalculate.

class Vector
    {
        float X;
        float Y;
        bool changed;
        float _length;

        void setX (float val) { // the same for Y
        X = val;
        changed = true;
        }
        float Length(){
           if (changed)
          //compute Length 
            changed = false;
            return ComputedValue;

       } 

}

Upvotes: 0

Related Questions