0

I have the following class (header file):

class Kinetics{
    double x;
    double y;
    double z;
public:
    Kinetics();
    Kinetics(double x_, double y_, double z_);
    Kinetics(const Kinetics & obj);
    ~Kinetics();

    double get_x();
    void set_x(double x_);
    Kinetics operator + (const Kinetics & obj);
    Kinetics operator * (double c);
    void operator = (const Kinetics & obj);
};

The operators + and * have been implemented (cpp) as:

Kinetics Kinetics::operator + (const Kinetics & obj){
    Kinetics aux(x + obj.x, y + obj.y, z + obj.z);
    return(aux);
}

and

Kinetics Kinetics::operator * (double c){
   Kinetics aux(x * c, y * c, z * c);
   return(aux);
}

Contrary to here: no match for operator*

I have declared and included the header file in my main program. I get the following message:

main.cpp:11: error: no match for ‘operator*’ in ‘2.0e+0 * v2’

And I cannot figure out why. The line of code that originates this error (main file) is:

Kinetics v4 = 2.0 * v2;

Any advise would be welcome. Thank you.

Community
  • 1
  • 1
Albionion
  • 53
  • 7

2 Answers2

0

This is why it is a bad idea to declare most binary operators as member functions - they are asymmetric. You need

class Kinetics;
Kinetics operator *(const Kinetics& k, double c);
Kinetics operator *(double c, const Kinetics&k) { return k*c; }

class Kinetics{
    double x;
    double y;
    double z;
public:
    Kinetics();
    Kinetics(double x_, double y_, double z_);
    Kinetics(const Kinetics & obj);
    ~Kinetics();

    double get_x();
    void set_x(double x_);
    Kinetics operator + (const Kinetics & obj);
    friend Kinetics operator * (const Kinetics& k, double c);
    void operator = (const Kinetics & obj);
};
0

There is a common pattern for implementing binary operators, in terms of the compound assignment operators. This avoids the need for friends, and gets you consistent behavior.

In your case, this looks like this:

class Kinetics {
  // all that stuff
public:
  Kinetics& operator +=(const Kinetics& rhs) {
    // implemented inline for less typing
    x += rhs.x;
    y += rhs.y;
    z += rhs.z;
    return *this;
  }
  Kinetics& operator *=(double rhs) {
    x *= rhs;
    y *= rhs;
    z *= rhs;
    return *this;
  }
}
// These are non-member, non-friend functions
// Again inline for my convenience
inline Kinetics operator +(Kinetics lhs, const Kinetics& rhs) {
  lhs += rhs; // lhs is already a copy
  return lhs;
}
inline Kinetics operator *(Kinetics lhs, double rhs) {
  lhs *= rhs; // You may be tempted to write "return lhs *= rhs;".
  return lhs; // Don't. That would prevent RVO.
}
inline Kinetics operator *(double lhs, Kinetics rhs) {
  rhs *= lhs; // Thanks for this being commutative
  return rhs; // this implementation works.
}
Sebastian Redl
  • 69,373
  • 8
  • 123
  • 157