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

This is a discussion on No Match For Operator+ ??????? within the C++ Programming forums, part of the General Programming Boards category; My Class: Code: #include <iostream> #include <string> using namespace std; class Integer { public: Integer(int i); Integer(std::string str); int getValue(); ...

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    167

    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*?????
    Last edited by Paul22000; 05-14-2008 at 12:12 AM.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,647
    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.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Apr 2008
    Posts
    167
    Quote Originally Posted by laserlight View Post
    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!!!

  4. #4
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,548
    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.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    Apr 2008
    Posts
    890
    Why are you creating functions like add, subtract, multiply, divide, etc. when you can just overload the operators? This is C++, not Java.

  6. #6
    Registered User
    Join Date
    May 2008
    Location
    Paris
    Posts
    248
    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?
    Last edited by MarkZWEERS; 05-14-2008 at 06:49 AM.

  7. #7
    Registered User
    Join Date
    Apr 2006
    Posts
    2,027
    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).
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  8. #8
    Registered User
    Join Date
    May 2008
    Location
    Paris
    Posts
    248
    Guess that is what the good old teacher always told us huh ;-)

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,647
    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>.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    The larch
    Join Date
    May 2006
    Posts
    3,573
    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.)
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  11. #11
    Registered User
    Join Date
    May 2008
    Location
    Paris
    Posts
    248
    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;
    }

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,647
    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.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #13
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,548
    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?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #14
    Registered User
    Join Date
    May 2008
    Location
    Paris
    Posts
    248
    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.

    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...

  15. #15
    Registered User
    Join Date
    Jan 2005
    Posts
    7,317
    >> 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.

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 9
    Last Post: 03-30-2009, 06:37 PM
  2. no match for 'operator>>'
    By Taka in forum C++ Programming
    Replies: 3
    Last Post: 03-30-2009, 12:17 AM
  3. Function validation.
    By Fhl in forum C Programming
    Replies: 10
    Last Post: 02-22-2006, 07:18 AM
  4. 2 array match
    By ajastru2000 in forum C++ Programming
    Replies: 5
    Last Post: 07-18-2003, 07:58 AM
  5. How do I match 2 files to print data.
    By sketchit in forum A Brief History of Cprogramming.com
    Replies: 0
    Last Post: 11-12-2001, 04:45 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21