1

I need to overload the * operator in c++. So I have made a class called Element which must overload this opperator to work on a double value stored within it. This is what I have done in the implementation file:

#include "Element.h"
#include <iostream>

using namespace std;

// Other code that is not relevant

Element Element::operator * ( const Element &obj)
{
    d *= obj.d;
    return *this;
}

This doesn't work. It throws an error saying: "no match for 'operator*' in '8 * c'

In the main file I have:

d = a = 8 * c - 4 + b;

where d, a, c and b are all objects of class Element

Tim
  • 73
  • 1
  • 2
  • 11
  • 2
    I'll recommend the [Operator Overloading FAQ](http://stackoverflow.com/q/4421706/46642). – R. Martinho Fernandes Sep 07 '11 at 11:46
  • 8 is not an `Element`. It is treated as an int. The code You show only allows multiplication of two `Element`. – erikH Sep 07 '11 at 11:50
  • how then do I get it to work with multiplication of an Element and an int? – Tim Sep 07 '11 at 11:52
  • How about reading the below answers? there is more than one example there.... – sara Sep 07 '11 at 11:57
  • [shameless self publicity] I wrote an [entry](http://definedbehavior.blogspot.com/2011/07/operator-overloading.html) about operator overloading that you might want to take a look at, in particular you should read about the differences between overloading a binary operator as a free function or a member function. – David Rodríguez - dribeas Sep 07 '11 at 12:39

5 Answers5

3

You really have to understand what you are doing here, you are overloading the '*' operator for the Element class, but you're doing so while expecting another element has a 'parameter'.

The code you wrote is actually expecting this kind of code

Element v, w, a;
a = v * w;

As mentionned, you might want to take a look at : http://www.learncpp.com/cpp-tutorial/92-overloading-the-arithmetic-operators/

ALOToverflow
  • 2,679
  • 5
  • 36
  • 70
  • hmm ok i have read a bit on the learCPP website.. am going to try and implement some of the code written there.. thanks for the help – Tim Sep 07 '11 at 11:51
1

that's because you overloaded operator * only for Element * Element, while for c * 8 you would have to implement Element Element::operator * ( const int i)

Andreas Grapentin
  • 5,499
  • 4
  • 39
  • 57
1

You can match the 8 * c expression (int, Element) with a non-member overload like

Element operator* (const Element& leftHandSide, const Element& rightHandSide){
   return Element( leftHandSide.d * rightHandSide.d);
}

By using const Element& you can make use of a constructor with a signature like Element::Element(int ) for type conversion.

Captain Giraffe
  • 14,407
  • 6
  • 39
  • 67
0

Your existing operator implementation allows you to multiply two Element objects together. But, according to the client code in your 'main file', you need to be able to multiply an Element object by a scalar value; 8 in this case.

So what you need is an additional operator which takes a double as its parameter: Something like the following:

Element Element::operator * ( const double scalar ) const
{
    const Element e( d * scalar );
    return e;
}

Here I am assuming that your Element class has a constructor which takes a single scalar parameter, and assigns it to d.

Note also that your existing implementation of operator* is semantically strange, as it mutates the internal state of d (with *= ). This is almost certainly not what you want...

Brian Fearon
  • 151
  • 5
0

I have a solution for you and a warning for your operator overload.

Solution:

#include <iostream>
using namespace std;

struct Element {
    double d;
    Element(double d) {this->d = d;}
    Element operator*(const Element &obj) {
        d *= obj.d;
        return *this;
    }
};

Element operator*(const int i, const Element& e) {
    return Element(static_cast<double>(i) * e.d);
}

ostream& operator<<(ostream& os, const Element& e) {
    os << e.d;
    return os;
}

int main() {
        Element e(2);
        cout << "Product of 8 and e: " << 8*e << '\n';

        // This shows why your overload is a bad idea:
        Element a(3);
        cout << "a is " << a << '\n'; // prints 3
        cout << "Now its product with e is: " << a*e << '\n'; // prints 6
        cout << "Surprise: a is now " << a << '\n'; // prints 6
}

Your original overload did not work, cause it wasn't even called. Your expression was similar to

a = 8*c

where 8 is of type int and when C++ parses this expression from left to right it sees that 8 is of type int and tries to search for an overload of operator*(const Element&) in the type int and it cannot find it, cause it does not know and is not supposed to know anything about your own user-defined type. So if you want your own class to interact with the other types you either need to embed an overload of operator* as a member function into that other type or declare it as the external function like I did in my solution.

Now the warning. Your original operator overload is ill-defined, cause it modifies the original object, which is considered to be an unexpected behavior. I show this in the code above. It's like multiplying 8 by 2 would give you 16, but at the same time make 16 out of your 8. What you really want to do is to create a new element in your multiplication operator and return it:

struct Element {
    double d;
    Element(double d) {this->d = d;}
    Element operator*( const Element &obj) {
        return Element(this->d * obj.d);
    }
};

Damn these answers take heck a lot of time... I should be working though :\

Anton Daneyko
  • 6,528
  • 5
  • 31
  • 59