0

I'm overloading operator * and + to read some class' variables from files. I have written the following code:

class X {
     
   public:
      double getLength(void) {
         return length;
      }
      void setLength( double len ) {
         length = len;
      } 
      
      // Overload + operator to add two Box objects.
     X operator*(X temp){
         X temp1;
         temp1.length = this->length * temp1.length;
         return temp1;
      }
      
      X operator*(int num){
         X temp1;
         temp1.length = this->length * num;
         return temp1; 
      }
      
     X operator+(X temp){ 
         X temp1;
         temp1.length = this->length + temp1.length;
         return temp1; 
      }
      
   private:
      double length;      // Length of a box
      
};

// Main function for the program
int main() {
   X ob1;                // Declare Box1 of type Box
   X ob2;                // Declare Box2 of type Box
   X ob3;                // Declare Box3 of type Box
   double result = 0.0;     // Store the volume of a box here
 
   ob2.setLength(6.0);  
   ob3.setLength(12.0);  
 
   ob1 = ob2 + 2*ob3;
   ob1 = ob2*2 + ob3;
   ob1 = (ob2 + 2) *ob3;
 
   cout << "length of Box  : " << ob1.getLength() <<endl;

   return 0;
}

But when I try to compile the above code, I am getting following error:

main.cpp: In function 'int main()':
main.cpp:48:17: error: no match for 'operator*' (operand types are 'int' and 'X')
    ob1 = ob2 + 2*ob3;
                ~^~~~
main.cpp:50:15: error: no match for 'operator+' (operand types are 'X' and 'int')
    ob1 = (ob2 + 2) *ob3;
           ~~~~^~~
main.cpp:27:8: note: candidate: 'X X::operator+(X)'
      X operator+(X temp){

I cant understand the error in my code. Please help me to solve the error.

Christopher Marlowe
  • 2,098
  • 6
  • 38
  • 68
  • 1
    The number has to be on the right for `X operator*(int num)`. – QuentinUK Dec 23 '21 at 23:32
  • 1
    The error messages explain what's going on pretty clearly. You have an overload that does `X * int`, but not one that does `int * X`. You have an overload that does `X + X`, but not one that does `X + int`. [More here](https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading) for what expected signatures are and why you probably want to implement these as free functions. – Nathan Pierson Dec 23 '21 at 23:33
  • For an expression like `2*ob3` to work there needs to be an `operator*()` that accepts an `int` as the first argument, and `X` as a second argument. You have only provided an `operator*()` that accepts an `X` as first argument and `int` as second argument. So you need to provide a non-member `X operator*(int, X)`. – Peter Dec 23 '21 at 23:35

2 Answers2

3

When you have operators as member functions, the left-hand side of an expression is the object that the function called on and the right-hand side is the object that becomes the argument.

So with your definitions:

ob3 * 2:;  // Fine: Calls ob3.operator*(2)
2 * ob3;   // Not fine, there's no operator* function which takes an int on the left-hand side

You can solve this by using non member functions:

X operator*(int a, X b)
{
    return b * a;  // Calls b.operator*(a)
}

Now you can have an int in the left-hand side:

2 * ob3;  // Fine: Calls operator+(2, ob3)

I also recommend this operator overloading canonical implementaiton reference. It recommends (among other thing) that you use operator*= and then implement operator* in terms of *=. For all binary operators.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
2

The error means what it says: There is no operator* for int * X and no operator+ for X + int. You only have overloaded operators for X * int, X * X and X + X.

You can add a converting constructor and make the operators free functions, then implicit conversions work on both operands (note that the getter should be const):

#include <iostream>

class X {         
   public:
      X(double length=0.0) : length(length) {}   // <- converting constructor
      double getLength() const {             // <- const !!!
         return length;
      }
      void setLength(double len) {
         length = len;
      } 
   private:
      double length;      // Length of a box          
};

X operator*(const X& a,const X& b){
    return {a.getLength() * b.getLength()};
}
     
X operator+(const X& a,const X& b){ 
    return {a.getLength() + b.getLength()}; 
}

int main() {
   X ob2{6.0};
   X ob3{12.0};
   X ob3;
 
   ob1 = ob2 + 2*ob3;
   ob1 = ob2*2 + ob3;
   ob1 = (ob2 + 2) *ob3;
 
   std::cout << "length of Box  : " << ob1.getLength() << std::endl;
}
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185