# No Match For Operator+ ???????

Printable View

Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last
• 05-13-2008
Paul22000
No Match For Operator+ ???????
My Class:

Code:

```#include <iostream> #include <string> using namespace std; class Integer {   public:     Integer(int i);     Integer(std::string str);     int getValue();     void setValue(int i);     void add(Integer& i);     void subtract(Integer& i);     void multiply(Integer& i);     void divide(Integer& i);   private:     int myInteger; };```
My Implementation:

Code:

```#include <iostream> #include <string> #include "integer.h" Integer::Integer(int i) {   myInteger = i; } Integer::Integer(std::string str) {   myInteger = atoi( str.c_str() ); } int Integer::getValue() {   return myInteger; } void Integer::setValue(int i) {   myInteger = i; } void Integer::add(Integer& i) {   myInteger = myInteger + i; } void Integer::subtract(Integer& i) {   myInteger = myInteger - i; } void Integer::multiply(Integer& i) {   myInteger = myInteger * i; } void Integer::divide(Integer& i) {   myInteger = myInteger / i; }```
Errors:

Code:

``` integer.cpp: In member function ‘void Integer::add(Integer&)’: integer.cpp:31: error: no match for ‘operator+’ in ‘((Integer*)this)->Integer::myInteger + i’ integer.cpp: In member function ‘void Integer::subtract(Integer&)’: integer.cpp:36: error: no match for ‘operator-’ in ‘((Integer*)this)->Integer::myInteger - i’ integer.cpp: In member function ‘void Integer::multiply(Integer&)’: integer.cpp:41: error: no match for ‘operator*’ in ‘((Integer*)this)->Integer::myInteger * i’ integer.cpp: In member function ‘void Integer::divide(Integer&)’: integer.cpp:46: error: no match for ‘operator/’ in ‘((Integer*)this)->Integer::myInteger / i’ make: *** [integer.o] Error 1 ```

Why is this happening??? Why can't I freaking *ADD*?????
• 05-14-2008
laserlight
Instead of:
Code:

`myInteger = myInteger + i;`
you probably intend to write:
Code:

`myInteger = myInteger + i.myInteger;`
or better yet:
Code:

`myInteger += i.myInteger;`
By the way, remove that using directive from your header. If you want to use it, use it in your source file instead. Also, for all the functions i should be a const Integer& since you do not modify it.
• 05-14-2008
Paul22000
Quote:

Originally Posted by laserlight
Instead of:
Code:

`myInteger = myInteger + i;`
you probably intend to write:
Code:

`myInteger = myInteger + i.myInteger;`
or better yet:
Code:

`myInteger += i.myInteger;`
By the way, remove that using directive from your header. If you want to use it, use it in your source file instead. Also, for all the functions i should be a const Integer& since you do not modify it.

THANKS!!!
• 05-14-2008
Elysia
You can't add an object (your class) because the compiler has no idea on how to do it. You can do it if you tell the compiler how to do it. It's called operator overloading. You'll probably get to it eventually.
• 05-14-2008
medievalelks
Why are you creating functions like add, subtract, multiply, divide, etc. when you can just overload the operators? This is C++, not Java.
• 05-14-2008
MarkZWEERS
Well, let's give him a hint! A very straightforward way, you will find this in basic text books, is to overload operators as class member functions:

Code:

```#include <iostream> #include <string> class Integer {   public:     Integer(int i);     Integer(std::string str);     int getValue();     void setValue(int i);     Integer& operator+( Integer const& arg); // why use 'Integer' AND 'int'   private:     int myValue; }; // *** Integer& Integer :: operator+( Integer const& arg) {     this->myValue += arg.myValue;     return *this; }```
However, try to minimize your class with functions that concern your (private) attributes in the most direct way only, e.g., the constructors (default, copy, cast, ..) 'setValue', 'getValue'. All other functions are best no-member, no-friend.

Why? Try to overload the operator+ for a class Double:

Code:

```#include <iostream> #include <string> class Double {   public:     Double(double i);     Double(std::string str);     double getValue();     void setValue(double i);     Double& operator+( Double const& arg); // suppose you have defined a class 'Double'     Double& operator+( Integer const& arg); // to add your Integer to your Double   private:     double myValue; }; // *** Integer& Integer :: operator+( Integer const& arg) {     this->myValue += arg.myValue;     return *this; } Double& Double:: operator+( Integer const& arg) {     this->myValue+= arg.myValue;     return *this; }```
This will work for ' double + int' , but it won't for ' int + double ' . Why? In the member-operator, '*this', so the double, is the left (implicit) argument of '+', and 'int' the right argument. You cannot invert these.
Now you can say: "Ok, but I simply write an 'operator+( Double)' in my class 'Integer' ". Wrong: you cannot declare this before the class 'Double' has been declared!

An even stronger argument: if you want to add an object of a class your colleague wrote, to your Integer, you cannot modify his/her class. And you do want this operator to be commutative.

There are better arguments, but let's hold for now.

I would try it like this:

Code:

```#include <iostream> #include <string> class Integer {   public:     Integer(); // no default constructor?     Integer(int i);     Integer(std::string str);     int getValue();     void setValue(int i);     Integer& operator+( Integer const& arg); // why use 'Integer' AND 'int' ?!   private:     int myValue; }; class Double {   public:     Double(); // don't you want a default constructor?     Double(double i); // not explicit to cast implicitely Double to Integer     Double(std::string str);     double getValue();     void setValue(double i);   private:     double myValue; }; // *** Integer& operator+( Integer const& arg1, Integer const& arg2) {     Integer result = arg1.myValue + arg2.myValue;     return result; } Double& operator+( Integer const& arg1, Double const& arg2) {     Double result = arg1.myValue + arg2.myValue;     return result; } Double& operator+( Double const& arg1, Integer const& arg2) {     Double result = arg1.myValue+ arg2.myValue;     return result; } Double& operator+( Double const& arg1, Double const& arg2) {     Double result = arg1.myValue + arg2.myValue;     return result; }```
Ok, only the operator with the two 'Double' arguments would have sufficed, since implicit casts are allowed (no 'explicit' keyword in the one-argument constructor). But to make the point...

And any 'operator@' should be defined, if possible, in the canonical way by calling the member 'operator@=' (this _must_ be a member, like '=').

EDIT: try to be as general as possible. Your class is called 'Integer', so why call the private attribute 'myInteger' ? Let's call it 'myValue'.

EDIT2: is #include <iostream> really always necessary?
• 05-14-2008
King Mir
No there is no point in including iostream unless you are using the standard io streams (in, cout, clog, cerr, and their wide character equivalents).
• 05-14-2008
MarkZWEERS
Guess that is what the good old teacher always told us huh ;-)
• 05-14-2008
laserlight
In this case I would #include <iosfwd> then overload of operators>> and << for I/O streams. In the implementation file, I would #include <istream> and <ostream>.
• 05-14-2008
anon
MarkZWEERS, may I point out that you seem to be confusing operators + and += (where + is implemented using += and returning *this)?

It seems that after you do c = a + b in some examples, b would be unmodified, but both a and c would contain the sum.

In the rest of the cases you are returning references to local objects. (Operator + should return a copy of the result.)
• 05-14-2008
MarkZWEERS
Oooops... copy-paste mistake.. sorry, here's a correction:

Code:

```#include <iostream> #include <string> class Integer {   public:     Integer(); // no default constructor?     Integer(int i);     Integer(std::string str);     int getValue();     void setValue(int i);   private:     int myValue; }; class Double {   public:     Double(); // don't you want a default constructor?     Double(double i); // not explicit to cast implicitely Double to Integer     Double(std::string str);     double getValue();     void setValue(double i);   private:     double myValue; }; // *** Integer operator+( Integer const& arg1, Integer const& arg2) {     Integer result = arg1.myValue + arg2.myValue;     return result; } Double operator+( Integer const& arg1, Double const& arg2) {     Double result = arg1.myValue + arg2.myValue;     return result; } Double operator+( Double const& arg1, Integer const& arg2) {     Double result = arg1.myValue+ arg2.myValue;     return result; } Double operator+( Double const& arg1, Double const& arg2) {     Double result = arg1.myValue + arg2.myValue;     return result; }```
• 05-14-2008
laserlight
MarkZWEERS, your code has a serious problem: operator+(const Integer&, const Integer&) is a non-member non-friend function, yet it directly accesses a private member variable of the Integer class.

Also, getValue() should be const, and perhaps it would be better to provide a non-explicit Double constructor that takes an Integer instead of having specific overloads to handle addition of a Double and an Integer. Oh, and std::string objects should be passed by (const) reference.
• 05-14-2008
Elysia
Any object should be preferred to be passed by a constant reference... That would make it possible for implicit conversions using the object's constructors.
Though I don't know if C++0x makes it legal for a non-const reference that can do the same?
• 05-14-2008
MarkZWEERS
Quote:

yet it directly accesses a private member variable of the Integer class
yes, I would make getValue() 'inline' and then call this function instead of erroneously accessing the private attribute.

Didn't touch the other things, so no credits for that...

Sorry for these stupid copy-paste errors, it's not very rigorous.

Quote:

it would be better to provide a non-explicit Double constructor to handle addition of a Double and an Integer
This is what I tried to point out in my first post...
• 05-14-2008
Daved
>> Oh, and std::string objects should be passed by (const) reference.
While I agree that this is generally a good idea, I don't see much problem using string as a value type in instances where performance should not be a problem. I doubt a string that holds a double or integer will be very big and expensive to copy anyway.
Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last