Thread: how to use operator+() in this code?

  1. #1
    Registered User
    Join Date
    Jul 2005
    Location
    Lahore, Pakistan
    Posts
    6

    how to use operator+() in this code?

    Hi guys!

    I don't know anything about how to use operator+(), I have just searched some sites(tutorial / articles) and have done what they have said, but didn't succeeded in compiling my program.

    Here is the code, (commenting the lines used for operator+())
    Code:
    #include <iostream>
    using namespace std;
    
    class math
    {
        private:
        int number;
    
        public:
        math();   //constructor of the class
    
    //    math operator+(math);
    
    math::math()
    {
        number = 0;
    }
    
    int main()
    {
        math obj1, obj2;
    //    int a = 10;
    //    obj1 = obj2 +a;
        obj1 = obj2 + 10;
    }
    
    math math::operator+(math obj)    //Also wrote (math obj, int x) and many other combinations
    {
        math temp;
        temp.number = obj.number + 10;
        return (temp);
    }
    Compiler says that, there is no operator+ for 'obj2 + 10'
    Last edited by barlas; 07-08-2005 at 05:33 AM.

  2. #2
    Skunkmeister Stoned_Coder's Avatar
    Join Date
    Aug 2001
    Posts
    2,572
    thats cos there isnt.
    Try this class

    Code:
    class math
    {
       private:
         int number;
       public:
         math operator +(const int added)
         {
            math temp(*this); // stupid cock-up sorted
            temp.number += added;
            return temp;
         }
    };
    Last edited by Stoned_Coder; 07-08-2005 at 05:42 AM.
    Free the weed!! Class B to class C is not good enough!!
    And the FAQ is here :- http://faq.cprogramming.com/cgi-bin/smartfaq.cgi

  3. #3
    aoeuhtns
    Join Date
    Jul 2005
    Posts
    581
    For starters, you don't want to be adding 10; you want to be adding the value of this->number.

    You can't add 10 to an object of your class because your class doesn't know how to add ints. 10 is a built-in int, not a math object. For that to work, you'd need to define the function operator+(int) as well.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    I think your class definition is not well formed.
    It might also be useful to use a global operator+, e.g.
    Code:
    class math {
    	friend math operator+(math a, math b);
    public:
    	math() : number(0) {}
    	math(int num) : number(num) {}
    private:
    	int number;
    };
    
    math operator+(math a, math b) {
    	return a.number + b.number;
    }
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Jul 2005
    Location
    Lahore, Pakistan
    Posts
    6
    Thanks everyone.

    Stoned_Coder it worked. Can you please explain a little how it worked? As, now I wanted to do obj1 = 10 + obj2 but it didn't worked, gave the same error as obj1=obj2+10 was giving before.

    Any help (or pointers) will be much appreciated

    Thanks again
    barlas

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    A few comments;

    The reason that Stoned_Coder's solution worked (+/- some minor things like adding missing semi-colons) is that he defined operator+ as a member of the class math;
    Code:
    math operator +(const int added)
         {
            math temp(*this);                 // this creates a copy of *this
            temp.number += added;      // increased temp.number by added ...
            return temp;                        //  and return the temporary copy
         }
    If x and y are both of type math, this code will be called in an example;
    Code:
       y = x + 10;
    which the compiler treats as;
    Code:
       y = x.operator+(10);
    Although it works, I wouldn't define it quite this way; instead of
    Code:
    class math
    {
         public:
           // constructors, etc
            math operator+(const int added);
    };
    I would recommend this ....
    Code:
    class math
    {
         public:
           // constructors, etc
            math operator+(int added) const;
    };
    The reason for changing the location of the const keyword is twofold. Firstly, an int passed by value remains constant as far as the caller is concerned. Secondly, const at the end of the declaration tells the compiler that the operation y = x + 10; does not change x.

    If you want to work with obj1 = 10 + obj2, and with obj1 = obj2 + 10; you need to provide two forms of operator+(), viz.
    Code:
    class math
    {
         public:
           // constructors, etc
            math operator+(int add) const;               // used for   y = x + 10
            friend math operator+(int value, const math &add);   // used for y = 10 + x;
    };
    
    math math::operator+(int add) const
    {
        math temp(*this);
        temp.number += add;
        return temp;
        //  alternate implementation if math has a constructor that takes an int argument
        //  math temp(number + add);
        //  return temp;
    }
    
    math operator+(int value, const math &add)
    {
         //  this assumes math has a constructor that accepts an int argument ....
           math temp(value + add.number);
           return temp;
    }
    Last edited by grumpy; 07-08-2005 at 08:33 AM. Reason: Fix typos

  7. #7
    Anti-Poster
    Join Date
    Feb 2002
    Posts
    1,401
    Alternately, instead of overloading the +operator multiple times, you could overload the int casting operator. Consider this:
    Code:
    #include <iostream>
    
    class math
    {
    public:
    	math(int a) : number(a) {}
    
    	operator int() {return number;}
    private:
    	int number;
    };
    
    int main()
    {
    	int a = 10;
    	math c(30);
    	std::cout << (c+a) << " " << (a+c) << " " << (c+c) << std::endl;
    	return 0;
    }
    This also allows you to pass your math class to any function expecting an int.
    If I did your homework for you, then you might pass your class without learning how to write a program like this. Then you might graduate and get your degree without learning how to write a program like this. You might become a professional programmer without knowing how to write a program like this. Someday you might work on a project with me without knowing how to write a program like this. Then I would have to do you serious bodily harm. - Jack Klein

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    If you want to work with obj1 = 10 + obj2, and with obj1 = obj2 + 10; you need to provide two forms of operator+()
    Just providing one global operator+ is sufficient, as per my previous example.
    Of course you also need a constructor that accepts an int, and one might implement operator+= first and use that to implement operator+
    e.g.
    Code:
    class math {
    public:
    	math() : number(0) {}
    	math(int num) : number(num) {}
    	void operator+=(math a);
    private:
    	int number;
    };
    
    void math::operator+=(math a) {
    	number += a.number;
    }
    
    math operator+(math a, math b) {
    	a += b;
    	return a;
    }
    instead of overloading the +operator multiple times, you could overload the int casting operator
    That might be cheating in this case, since the OP might as well not even implement such a simplistic math class. I think the whole idea of this math class was for the OP to learn how to handle operator+.
    Last edited by laserlight; 07-08-2005 at 11:22 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Skunkmeister Stoned_Coder's Avatar
    Join Date
    Aug 2001
    Posts
    2,572
    ok that code was written in about 15 secs as i was just on way out the door. It is true that operator + is best written as a non-member but it can be written as a class member too.
    As grumpy points out the int passed need not be const( and pros will often never make that const) but i always make it const as it helps with newbie protection. I have seen things like this before...
    Code:
    math operator +(int a)
    {
       a=10;
       // blah blah
    }
    The const protects you from such silly screw-ups. Most would say, "i'll never do that", but believe me it happens, especially when a function gains a little length, so for examples I always use const there, because at least then if the above or similar was to happen the compiler cathes the error for you rather than silently allowing it. I didnt make it a const member function because I wasn't sure you were ready for that yet and I thought it may confuse you. I think its often best to learn class-writing in stages.
    Now how does it work?
    Well for starters when you write a class as I have above giving it no constructors then the compiler will happily make 4 functions for us. These are a default constructor, a copy constructor, a copy assignment operator and a destructor. As long as you have a simple POD(plain old data) type you can rely on these compiler generated functions to do the right thing. When you start having pointers to dynamic memory inside your class you will need to provide these functions for yourself. Here our only member is an int so the compiler generated functions are fine. Now lets see what each does.
    The default constructor is called when you create an object of the class passing no constructor params i.e.
    Code:
    math obj;
    This will zero all members for you.So after this line with the class I gave you obj.number will be zero.
    Next the copy constructor. This is called when you make a new object from an existing object of the class. Lets see a couple of copy constructor calls...
    Code:
    math obj; // default construcor called
    math copy_obj(obj); // copy constructor called EXPLICITLY
    math copy_obj_again = obj; // copy constructor called IMPLICITLY
    Now copy assignment. This is called when you want to make one object equal another but both already exist. This is an assignment operator call.
    Code:
    math obj; // make object
    math obj2(20); // using an imaginary int constructor(not yet written)
    obj = obj2; // copy assignment op called
    now the destructor. This is called automagically by your compiler whenever an object leaves scope. Its purpose is to destroy your object.
    Code:
    {
       math obj;
       math obj2(obj);
    } // here at the bracket those two above objects lose scope and the destructor will be called for each one
    Armed with that information you should be able to see how the operator + I gave you works.
    this is a pointer to the current object. *this IS the current object. So from within the class...
    Code:
    math obj(*this);
    Is a copy constructor call. It makes a new math object called obj initialised with the current math object.
    Code:
    obj.number += added;
    Although number is private, we are inside the class here and can refer to it. This simple line just adds the two ints together and stuffs the result back into obj.number.
    The final line of the function returns the new object by value.
    One important point is that above I called a constructor taking an int. If you provide this constructor then the compiler generated constructors disappear and if you want their functionality then you have to write them yourself.
    Enjoy.
    Free the weed!! Class B to class C is not good enough!!
    And the FAQ is here :- http://faq.cprogramming.com/cgi-bin/smartfaq.cgi

  10. #10
    Registered User
    Join Date
    Jul 2005
    Location
    Lahore, Pakistan
    Posts
    6
    Thanks guys, for all the help and info!

  11. #11
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by pianorain
    Alternately, instead of overloading the +operator multiple times, you could overload the int casting operator. Consider this:
    Code:
    #include <iostream>
    
    class math
    {
    public:
    	math(int a) : number(a) {}
    
    	operator int() {return number;}
    private:
    	int number;
    };
    
    int main()
    {
    	int a = 10;
    	math c(30);
    	std::cout << (c+a) << " " << (a+c) << " " << (c+c) << std::endl;
    	return 0;
    }
    This also allows you to pass your math class to any function expecting an int.
    Conversion operators of classes have a few gotchas: in particular, in some cases, you can find an object of type "math" being silently converted to an int when you really don't want it to be.

    An example where you wouldn't want a math object converted to int would be if you used the math object to represent values larger than can be stored in an int.

    Consider this example;
    Code:
    //   assume sizeof(int) is 2, so maximum value that can
    //    be stored in an int is about 32767
    //
    //    There ARE compilers that do this!
    
    
    #include <limits.h>    // for INT_MAX and INT_MIN
                                      //   we could use <limits> but code to get max
                                      //     and min value of an int is more verbose
    
    class AlternateMath
    {
         public:
    
              AlternateMath(int x = 0) {value[0] = x; value[1] = 0;};
    
              AlternateMath operator+(int x) const;
    
       private:
              int value[2];
    };
    
    AlternateMath AlternateMath::operator+(int x) const
    {
          AlternateMath temp(*this);
         if (x > 0)
         {
                   if (value[0] > INT_MAX - x)
                   {
                        ++temp.value[1];
                        temp.value[0] = INT_MAX - x;
                   }
                   else
                   {
                         temp.value[0] += x;
                   }
        }
        else if (x < 0)
        {
                 // similar sort of logic to work with -ve x
        } 
        return temp;
    
    }
    
    int main()
    {
          AlternateMath x(32000);
          AlternateMath y(x + 32000);
          Alternate z(32000 + y);
    }
    If we provided an operator int() for this class, the above code would compile, but the value stored in z would definitely not be 96000.

    The only way to get the intended behaviour in this instance would be to provide multiple operator+() for AlternateMath, to take arguments in various combinations.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Extended ASCII Characters in an RTF Control
    By JustMax in forum C Programming
    Replies: 18
    Last Post: 04-03-2009, 08:20 PM
  2. Enforcing Machine Code Restrictions?
    By SMurf in forum Tech Board
    Replies: 21
    Last Post: 03-30-2009, 07:34 AM
  3. Obfuscated Code Contest
    By Stack Overflow in forum Contests Board
    Replies: 51
    Last Post: 01-21-2005, 04:17 PM
  4. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM
  5. Replies: 0
    Last Post: 02-21-2002, 06:05 PM