5

I am trying to find a simple example program that overloads the following operators of a mathematic vector.

Constructor  // create

= (equals)     // assign

+; -; +=; -=   // add sub

*; /; *=; /=   // multi divide

++; -- // plus minus

==    // compare
>; >=
<; <=

[]    // access a value

Cant seem to find any good simple tutorials. I emphasize the simple because I am only learning this stuff now. If someone could link me or even better program a simple overload for just one of the operators as an example would be incredible!

5
  • When you say "mathematical vector" what actual type is it? Commented Oct 31, 2013 at 2:34
  • Like this? cplusplus.com/doc/tutorial/classes2 Commented Oct 31, 2013 at 2:35
  • In future work at uni i got told we will be using "mathematical vector, not STL vector" so not sure if they are same thing or different. Commented Oct 31, 2013 at 2:37
  • also if i have to make a 'vector class object' what does that mean? Is the a class that inherits from vector? Commented Oct 31, 2013 at 2:46
  • I would think that a "mathematical" vector means a vector of coordinates, not an array of objects. Commented Oct 31, 2013 at 2:56

1 Answer 1

13

There are a few things to know when you write operators, which are not as often used with other functions.

The assign operators, for example, will return *this because you change the value of the vector:

class v {
public:
  double x_, y_;
  v& operator += (const v& rhs)
  {
     _x += rhs._x;
     _y += rhs._y;
     return *this;
  }
};

Another interesting one, the pre ++ and post ++ are different only because of an unused parameter:

class v {
public:
  double x_, y_;
  v& operator ++ (); // ++v
  v& operator ++ (int); // v++
};

The "equal" (assignment) is another one that is tricky when you use pointers. For a vector, it generally won't be a problem, but if you define a vector V and assign it to itself, you have to be careful:

class v {
public:
  double x_, y_;
  v& operator = (const v& rhs)
  {
    if(this != &rhs)
    {
      x_ = rhs.x_;
      y_ = rhs.y_;
    }
    return *this;
  }
};

In your case, the if() will most certainly not be useful, but think about doing something like this:

   delete p_;
   p_ = new foo;
   p_->x_ = rhs.p_->x_;

If &rhs == this, then the delete p_ deleted the rhs pointer! That means accessing it on the 3rd line is a bug.

The rest should be easy enough to work with. The compare operators return bool and are const:

class v {
public:
  double x_, y_;
  bool operator == (const v& rhs) const
  {
    return x_ == rhs.x_ && y_ == rhs.y_;
  }
};

Although, since C++20, you are expected to only declare the three way comparison operator <=> which allows the compiler to implement all the other comparison operators for you. This one returns a negative number (smaller: a < b), 0 (equal: a == b), or a positive number (larger: a > b).

I'm not sure what makes a vector bigger or smaller, I used the length from (0, 0) in this example:

class v {
public:
  double x_, y_;
  int operator <=> (const v& rhs) const
  {
    if(x_ == rhs.x_ && y_ == rhs.y_)
    {
      return 0;
    }
    return length() > rhs.length() ? 1 : -1;
  }
};

Except for the [] operator. There are two versions of that one:

class v {
public:
  // I would imagine you'd use an array but as a simple example...
  double x_, y_;
  double operator [] (int idx) const
  {
    return idx == 0 ? x_ : y_;
  }
  v_ref operator [] (int idx)
  {
    v_ref v(this, idx);
    return v;
  }
};

As you can see, the non-constant version of the [] operator returns a reference. This is necessary so you can write something like:

r[3] = 7.3;

r[3] returns that reference, then the assignment of the reference is called with 7.3 as the parameter. (Note that we should probably throw an error if you use 3 as the index when you only have 2 values: 0 and 1--this is not shown here)

class v_ref
{
public:
  v *p_;
  int i_;
  v_ref(v *p, int i)
    : p_(p), i_(i)
  {
  }
  operator = (double q)
  {
     // again, I suppose you'd use an array instead!
     if(i_ == 0)
     {
       p_->x_ = q;
     }
     else
     {
       p_->y_ = q;
     }
  }
};

Assuming you want some security, the vector pointer could make use of a reference counter so you know whether a main vector object gets deleted before all of its reference objects...

Another note: I would imagine that your constructor will allocate an array of double (or use an std::vector<double> type...) If you use new, remember to delete in the destructor and that's when the if() in the assignment operator is very important.

Sign up to request clarification or add additional context in comments.

3 Comments

How do i create a Vector Class Object though to implement this stuff in?
@user2495847 So you don't even have your vector class yet? It sounds like you need to start with some basic C++ class tutorials.
@crashmstr I am being asked to create a Vector Class Object so does that mean create a vector like so... vector <v> using the code shown above or does it mean to... class myVector : std::vector<int> { ... }; sort of thing?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.