Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Basic operator overloading

Basic operator overloading

Scheduled Pinned Locked Moved C / C++ / MFC
questiondatabasetutoriallearning
12 Posts 6 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    bkelly13
    wrote on last edited by
    #1

    I am having a difficult time understand what is really happening when I overload an operator for a class. Here is my class declaration. CC is short for CCarteseanCordinates.

    class CC
    {
    public:
    CC(void);
    ~CC(void);

    CC operator+( CC &source );
    
    double Query\_X();
    double Query\_Y();
    double Query\_Z();
    
    void Set\_X( double value );
    void Set\_Y( double value );
    void Set\_Z( double value );
    

    protected:
    double X;
    double Y;
    double Z;
    };

    Attempting to follow format of the example in the book I have, the definition of the + operator overload is:

    1 CC CC::operator+( CC &source )
    2 {
    3 CC result = *this;
    4 double sum = source.Query_X() + X;
    5 result.Set_X( sum );
    6// repeat for Y
    7// repeat for Z
    8 return result;
    9 };

    Line 3 starts with

    CCarteseanCordinates result

    Which seems to create a local object of type CCarteseanCordinates. Now adding on the = *this;, the line now seems to say assign to that object the value of the local this pointer. That is similar to writing

    Int y;
    Int *z = &y;
    Int x = *y

    Except: The equal operator has not been overloaded so

    Object1 = object2;

    Is not a valid construct. Should my declaration really be something like:

    CC operator+( CC &source1, CC &source2 );

    What is really going on here, and what should be going on? Lets ignore the friend operator for the moment.

    Thanks for your time

    S L D 3 Replies Last reply
    0
    • B bkelly13

      I am having a difficult time understand what is really happening when I overload an operator for a class. Here is my class declaration. CC is short for CCarteseanCordinates.

      class CC
      {
      public:
      CC(void);
      ~CC(void);

      CC operator+( CC &source );
      
      double Query\_X();
      double Query\_Y();
      double Query\_Z();
      
      void Set\_X( double value );
      void Set\_Y( double value );
      void Set\_Z( double value );
      

      protected:
      double X;
      double Y;
      double Z;
      };

      Attempting to follow format of the example in the book I have, the definition of the + operator overload is:

      1 CC CC::operator+( CC &source )
      2 {
      3 CC result = *this;
      4 double sum = source.Query_X() + X;
      5 result.Set_X( sum );
      6// repeat for Y
      7// repeat for Z
      8 return result;
      9 };

      Line 3 starts with

      CCarteseanCordinates result

      Which seems to create a local object of type CCarteseanCordinates. Now adding on the = *this;, the line now seems to say assign to that object the value of the local this pointer. That is similar to writing

      Int y;
      Int *z = &y;
      Int x = *y

      Except: The equal operator has not been overloaded so

      Object1 = object2;

      Is not a valid construct. Should my declaration really be something like:

      CC operator+( CC &source1, CC &source2 );

      What is really going on here, and what should be going on? Lets ignore the friend operator for the moment.

      Thanks for your time

      S Offline
      S Offline
      Saurabh Garg
      wrote on last edited by
      #2

      In a class Constructor, Copy Constructor and assignment operator are automatically generated by compiler if needed. First and most important is the definition of operator. You should understand that operator is nothing by a function. So for CC class if you write a = b + c, where a, b, and c are objects of type CC, what it really means is a = b.operator+(c). Does this makes sense? Another this is there is no need to use functions to access variables within the class. You can do this as:

      CC CC::operator+(CC &source)
      {
      CC result = *this;

      result.X += source.X;
      result.Y += source.Y;
      result.Z += source.Z;
      
      return result;
      

      }

      Hope this helps. -Saurabh

      B 2 Replies Last reply
      0
      • B bkelly13

        I am having a difficult time understand what is really happening when I overload an operator for a class. Here is my class declaration. CC is short for CCarteseanCordinates.

        class CC
        {
        public:
        CC(void);
        ~CC(void);

        CC operator+( CC &source );
        
        double Query\_X();
        double Query\_Y();
        double Query\_Z();
        
        void Set\_X( double value );
        void Set\_Y( double value );
        void Set\_Z( double value );
        

        protected:
        double X;
        double Y;
        double Z;
        };

        Attempting to follow format of the example in the book I have, the definition of the + operator overload is:

        1 CC CC::operator+( CC &source )
        2 {
        3 CC result = *this;
        4 double sum = source.Query_X() + X;
        5 result.Set_X( sum );
        6// repeat for Y
        7// repeat for Z
        8 return result;
        9 };

        Line 3 starts with

        CCarteseanCordinates result

        Which seems to create a local object of type CCarteseanCordinates. Now adding on the = *this;, the line now seems to say assign to that object the value of the local this pointer. That is similar to writing

        Int y;
        Int *z = &y;
        Int x = *y

        Except: The equal operator has not been overloaded so

        Object1 = object2;

        Is not a valid construct. Should my declaration really be something like:

        CC operator+( CC &source1, CC &source2 );

        What is really going on here, and what should be going on? Lets ignore the friend operator for the moment.

        Thanks for your time

        L Offline
        L Offline
        Luc Pattyn
        wrote on last edited by
        #3

        Hi, CC result= *this; does not create anything; it declares a reference called result to a type CC and sets it equal to *this, so now result and this are one and the same object. IMO it was not really necessary; there must be a way to do *this.Set_X(sum) directly) in your line 5. :)

        Luc Pattyn [Forum Guidelines] [My Articles]


        Voting for dummies? No thanks. X|


        modified on Sunday, July 6, 2008 5:31 PM

        G 1 Reply Last reply
        0
        • L Luc Pattyn

          Hi, CC result= *this; does not create anything; it declares a reference called result to a type CC and sets it equal to *this, so now result and this are one and the same object. IMO it was not really necessary; there must be a way to do *this.Set_X(sum) directly) in your line 5. :)

          Luc Pattyn [Forum Guidelines] [My Articles]


          Voting for dummies? No thanks. X|


          modified on Sunday, July 6, 2008 5:31 PM

          G Offline
          G Offline
          Graham Shanks
          wrote on last edited by
          #4

          Luc Pattyn wrote:

          CC result= *this; does not create anything; it declares a reference called result to a type CC and sets it equal to *this, so now result and this are one and the same object.

          Sorry, that statement is not correct.

          CC result= *this;

          creates an object of type CC and assigns the contents of the current object to it. To create a reference you would use CC& result = *this; Actually the above code probably does not use the assigment operator, it may well use the copy constructor (the compiler is allowed to treat declaration and assignment in one statement as copy construction rather than default construction followed by assignment).

          Graham Librarians rule, Ook!

          L 1 Reply Last reply
          0
          • G Graham Shanks

            Luc Pattyn wrote:

            CC result= *this; does not create anything; it declares a reference called result to a type CC and sets it equal to *this, so now result and this are one and the same object.

            Sorry, that statement is not correct.

            CC result= *this;

            creates an object of type CC and assigns the contents of the current object to it. To create a reference you would use CC& result = *this; Actually the above code probably does not use the assigment operator, it may well use the copy constructor (the compiler is allowed to treat declaration and assignment in one statement as copy construction rather than default construction followed by assignment).

            Graham Librarians rule, Ook!

            L Offline
            L Offline
            Luc Pattyn
            wrote on last edited by
            #5

            Hi, I believe you are right, I was looking through my C# glasses once more. :)

            Luc Pattyn [Forum Guidelines] [My Articles]


            Voting for dummies? No thanks. X|


            1 Reply Last reply
            0
            • S Saurabh Garg

              In a class Constructor, Copy Constructor and assignment operator are automatically generated by compiler if needed. First and most important is the definition of operator. You should understand that operator is nothing by a function. So for CC class if you write a = b + c, where a, b, and c are objects of type CC, what it really means is a = b.operator+(c). Does this makes sense? Another this is there is no need to use functions to access variables within the class. You can do this as:

              CC CC::operator+(CC &source)
              {
              CC result = *this;

              result.X += source.X;
              result.Y += source.Y;
              result.Z += source.Z;
              
              return result;
              

              }

              Hope this helps. -Saurabh

              B Offline
              B Offline
              bkelly13
              wrote on last edited by
              #6

              RE: what it really means is a = b.operator+(c). No, I am missing several things here. Lets skip around a bit. First + (the plus symbol) is a binary operator as in:

              int a, b, c;
              a = b + c;

              That means it has two arguments. To write this in the form of a function we would use the format:

              result = add( y, z );

              So there should be two arguments in the declaration. But when I write this in the dot h file:

              CC operator+( CC &source1, CC &source2 )

              The compiler says: error C2804: binary 'operator +' has too many parameters That seems to be in direct contradiction of the form:

              a = b + c;

              The addition operator has three variables, one left and two right. As the values are being put in x, and read from y and z, it seems that the function is being run from the perspective of object x. What am I missing? I have another question, but lets take this one point at a time.

              Thanks for your time

              B 1 Reply Last reply
              0
              • B bkelly13

                I am having a difficult time understand what is really happening when I overload an operator for a class. Here is my class declaration. CC is short for CCarteseanCordinates.

                class CC
                {
                public:
                CC(void);
                ~CC(void);

                CC operator+( CC &source );
                
                double Query\_X();
                double Query\_Y();
                double Query\_Z();
                
                void Set\_X( double value );
                void Set\_Y( double value );
                void Set\_Z( double value );
                

                protected:
                double X;
                double Y;
                double Z;
                };

                Attempting to follow format of the example in the book I have, the definition of the + operator overload is:

                1 CC CC::operator+( CC &source )
                2 {
                3 CC result = *this;
                4 double sum = source.Query_X() + X;
                5 result.Set_X( sum );
                6// repeat for Y
                7// repeat for Z
                8 return result;
                9 };

                Line 3 starts with

                CCarteseanCordinates result

                Which seems to create a local object of type CCarteseanCordinates. Now adding on the = *this;, the line now seems to say assign to that object the value of the local this pointer. That is similar to writing

                Int y;
                Int *z = &y;
                Int x = *y

                Except: The equal operator has not been overloaded so

                Object1 = object2;

                Is not a valid construct. Should my declaration really be something like:

                CC operator+( CC &source1, CC &source2 );

                What is really going on here, and what should be going on? Lets ignore the friend operator for the moment.

                Thanks for your time

                D Offline
                D Offline
                Dan 0
                wrote on last edited by
                #7

                The code is fine, the compiler will generate operator= and the copy constructor for you, it's simply implicit instead of explicit. Rhe default implementation is a simple bitwise copy. The way the compiler generates the copy is sort of like:

                ClassA::ClassA( const ClassA &from)
                :member1( from.member1 )
                ,member2( from.member2 )
                ,.... etc
                {}

                This is perfectly fine for this class since you don't have any pointers to worry about. The default for operator= is functionally the same as the copy constructor. So your code for operator+ is correct. this is copied to result. result is modified. this actually remains constant. So actually to be on the safe side you should do.

                ......
                CC operator+( CC &source ) const;
                ......
                CC CC::operator+( CC &source ) const
                {
                CC result = *this;
                double sum = source.Query_X() + X;
                result.Set_X( sum );
                return result;
                }

                B 1 Reply Last reply
                0
                • B bkelly13

                  RE: what it really means is a = b.operator+(c). No, I am missing several things here. Lets skip around a bit. First + (the plus symbol) is a binary operator as in:

                  int a, b, c;
                  a = b + c;

                  That means it has two arguments. To write this in the form of a function we would use the format:

                  result = add( y, z );

                  So there should be two arguments in the declaration. But when I write this in the dot h file:

                  CC operator+( CC &source1, CC &source2 )

                  The compiler says: error C2804: binary 'operator +' has too many parameters That seems to be in direct contradiction of the form:

                  a = b + c;

                  The addition operator has three variables, one left and two right. As the values are being put in x, and read from y and z, it seems that the function is being run from the perspective of object x. What am I missing? I have another question, but lets take this one point at a time.

                  Thanks for your time

                  B Offline
                  B Offline
                  Bram van Kampen
                  wrote on last edited by
                  #8

                  bkelly13 wrote:

                  That means it has two arguments

                  Yes, it is just written down differently.:- a=b.operator+(c); The First argument is the object carrying out the addition, the second argument is the item being added. I.E. the Operator+ MEMBER FUNCTION adds a value to the object from which it is called, and passes the result, without modifying itself, The form c=add(a,b) is typically a global addition function. Answers to the other issues you raised follow directly when you grasp the concept of the above. Regards :)

                  Bram van Kampen

                  1 Reply Last reply
                  0
                  • S Saurabh Garg

                    In a class Constructor, Copy Constructor and assignment operator are automatically generated by compiler if needed. First and most important is the definition of operator. You should understand that operator is nothing by a function. So for CC class if you write a = b + c, where a, b, and c are objects of type CC, what it really means is a = b.operator+(c). Does this makes sense? Another this is there is no need to use functions to access variables within the class. You can do this as:

                    CC CC::operator+(CC &source)
                    {
                    CC result = *this;

                    result.X += source.X;
                    result.Y += source.Y;
                    result.Z += source.Z;
                    
                    return result;
                    

                    }

                    Hope this helps. -Saurabh

                    B Offline
                    B Offline
                    bkelly13
                    wrote on last edited by
                    #9

                    RE: So for CC class if you write a = b + c, where a, b, and c are objects of type CC, what it really means is a = b.operator+(c). Does this makes sense? NO, it really does not make sense. The value being written is going into object a and the function should be called from the perspective of object a. To operate from the b perspective is counter-intuitive and just flat bad design. If we follow this up logically, a unary operation such as += should have one less argument, or zero arguments. However, that’s not my call so I had best learn to deal with it. Regardless, lets see where this goes. The declaration looks like:

                    CC operator+( CC &source1 );

                    And the code looks like:

                    CC CC::operator+( CC &source1)
                    {
                    CC result = *this;
                    double sum = source1.X + X;
                    result.X = sum ;
                    // repeat for Y
                    // repeat for Z
                    return result;
                    };

                    And if I follow what your write, which is not certain, the code is executed from the perspective of object b. As I did not include the qualification “friend” in the declaration, code running from b does not have access to private variables in object a or in object c. That means that I should not have direct access to result.X or source1.X. So how can the compiler accept this code without error? It should force me to write:

                    double sum = X + source1.Get\_X();
                    result.Set\_X = sum;
                    

                    in the first line, X is from the b object, source1.Get_X() gets the value from the c object, and in the third line result goes to the a object. Given that the perspective is as you noted: a = b.operator+(c), why does the function have direct access to private members in objects a and c? Although I have not yet figured this out, thank you for taking the time to respond.

                    Thanks for your time

                    S 2 Replies Last reply
                    0
                    • D Dan 0

                      The code is fine, the compiler will generate operator= and the copy constructor for you, it's simply implicit instead of explicit. Rhe default implementation is a simple bitwise copy. The way the compiler generates the copy is sort of like:

                      ClassA::ClassA( const ClassA &from)
                      :member1( from.member1 )
                      ,member2( from.member2 )
                      ,.... etc
                      {}

                      This is perfectly fine for this class since you don't have any pointers to worry about. The default for operator= is functionally the same as the copy constructor. So your code for operator+ is correct. this is copied to result. result is modified. this actually remains constant. So actually to be on the safe side you should do.

                      ......
                      CC operator+( CC &source ) const;
                      ......
                      CC CC::operator+( CC &source ) const
                      {
                      CC result = *this;
                      double sum = source.Query_X() + X;
                      result.Set_X( sum );
                      return result;
                      }

                      B Offline
                      B Offline
                      bkelly13
                      wrote on last edited by
                      #10

                      Hello Dan, I am rather certain I agree about the const. However, I am a bit weak on exactly where the const goes to effect which part of a declaration. For the moment, I want to keep the thread as simple as I can. I will get back to the const in another thread. Thanks for the reminder.

                      Thanks for your time

                      1 Reply Last reply
                      0
                      • B bkelly13

                        RE: So for CC class if you write a = b + c, where a, b, and c are objects of type CC, what it really means is a = b.operator+(c). Does this makes sense? NO, it really does not make sense. The value being written is going into object a and the function should be called from the perspective of object a. To operate from the b perspective is counter-intuitive and just flat bad design. If we follow this up logically, a unary operation such as += should have one less argument, or zero arguments. However, that’s not my call so I had best learn to deal with it. Regardless, lets see where this goes. The declaration looks like:

                        CC operator+( CC &source1 );

                        And the code looks like:

                        CC CC::operator+( CC &source1)
                        {
                        CC result = *this;
                        double sum = source1.X + X;
                        result.X = sum ;
                        // repeat for Y
                        // repeat for Z
                        return result;
                        };

                        And if I follow what your write, which is not certain, the code is executed from the perspective of object b. As I did not include the qualification “friend” in the declaration, code running from b does not have access to private variables in object a or in object c. That means that I should not have direct access to result.X or source1.X. So how can the compiler accept this code without error? It should force me to write:

                        double sum = X + source1.Get\_X();
                        result.Set\_X = sum;
                        

                        in the first line, X is from the b object, source1.Get_X() gets the value from the c object, and in the third line result goes to the a object. Given that the perspective is as you noted: a = b.operator+(c), why does the function have direct access to private members in objects a and c? Although I have not yet figured this out, thank you for taking the time to respond.

                        Thanks for your time

                        S Offline
                        S Offline
                        Saurabh Garg
                        wrote on last edited by
                        #11

                        I think the biggest thing you are missing is that member functions of a class have full access to all member variables. It doesnt matter which object called the function, all objects of that class can access private members in a member function of same class. Lets take an example

                        class Foo
                        {
                        private:

                        int x;
                        

                        public:

                        Foo(int \_x)
                        {
                            x = \_x;
                        }
                        
                        inline int AddX(const Foo& B)
                        {
                            return x + B.x;
                        }
                        

                        };

                        Now you might think that it is a bad design to make private variable accessible - A can access B' x and vice-versa. But that is not the case. Why is it so? Because access modifies are for the classes which use this class. So for example if you want to hide member variables from other classes you will use private. These member variable will still be visible within the class definition. Now lets see if this was not the case. Then you must have a public function to set and get value for every private variable. Well in this case the private variables are as good as public variables. Does this make sense? Okay this is c++ side of the explanation. Lets work on intuition of how a = b + c should work. In the class definition I gave above I can do the following.

                        Foo f1(10);
                        Foo f2(2);
                        int y = f1.AddX(f2);

                        Look at it carefully it has, mathematically, same structure as a = b + c. But will you in this case say that since y is the return value the function should be called in perspective of y? And AddX should have two arguments instead of one? I hope answer to these questions in no. Now lets see how to read a = b + c in terms of c++ -> call b's member function operator+ with a single argument c and return a value a. In simpler words a = b.operator+(c). Now since a, b, and c are objects of same class the function operator+ (which is member of same class) have full access to class data. If we add operator+ to Foo it will look like.

                        class Foo
                        {
                        private:

                        int x;
                        

                        public:

                        Foo(int \_x)
                        {
                            x = \_x;
                        }
                        
                        inline int AddX(const Foo& B)
                        {
                            return x + B.x;
                        }
                        
                        Foo& operator+(const Foo& B)
                        {
                            Foo a;
                            a.x = x + B.x // Or a.x = this.x + B.x
                        }
                        

                        };

                        Only differece unary operator+ has is that it operates on same object which calls the function instead of creating a new one.

                        Foo& operator+(const Foo& B)
                        {
                        x = x + B.x;
                        return *this;
                        }

                        I hope this makes things a bit clearer now. -Saurabh

                        1 Reply Last reply
                        0
                        • B bkelly13

                          RE: So for CC class if you write a = b + c, where a, b, and c are objects of type CC, what it really means is a = b.operator+(c). Does this makes sense? NO, it really does not make sense. The value being written is going into object a and the function should be called from the perspective of object a. To operate from the b perspective is counter-intuitive and just flat bad design. If we follow this up logically, a unary operation such as += should have one less argument, or zero arguments. However, that’s not my call so I had best learn to deal with it. Regardless, lets see where this goes. The declaration looks like:

                          CC operator+( CC &source1 );

                          And the code looks like:

                          CC CC::operator+( CC &source1)
                          {
                          CC result = *this;
                          double sum = source1.X + X;
                          result.X = sum ;
                          // repeat for Y
                          // repeat for Z
                          return result;
                          };

                          And if I follow what your write, which is not certain, the code is executed from the perspective of object b. As I did not include the qualification “friend” in the declaration, code running from b does not have access to private variables in object a or in object c. That means that I should not have direct access to result.X or source1.X. So how can the compiler accept this code without error? It should force me to write:

                          double sum = X + source1.Get\_X();
                          result.Set\_X = sum;
                          

                          in the first line, X is from the b object, source1.Get_X() gets the value from the c object, and in the third line result goes to the a object. Given that the perspective is as you noted: a = b.operator+(c), why does the function have direct access to private members in objects a and c? Although I have not yet figured this out, thank you for taking the time to respond.

                          Thanks for your time

                          S Offline
                          S Offline
                          Saurabh Garg
                          wrote on last edited by
                          #12

                          After posting I realized that another example might make thinks more clearer.

                          class Foo
                          {
                          public:

                          Foo(int \_x)
                          {
                          	x = \_x;
                          }
                          
                          Foo& Add(const Foo& B)
                          {
                          	Foo a;
                          	a.x = x + B.x;
                          	return a;
                          }
                          

                          private:

                          int x;
                          

                          };

                          Foo a(10);
                          Foo b(20);
                          Foo c = a.Add(b);

                          Now instead of Add using operator and then imagine that compiler cannot see operator word in the code using this class. You will get.

                          class Foo
                          {
                          public:

                          Foo(int \_x)
                          {
                          	x = \_x;
                          }
                          
                          Foo& operator+(const Foo& B)
                          {
                          	Foo a;
                          	a.x = x + B.x;
                          	return a;
                          }
                          

                          private:

                          int x;
                          

                          };

                          Foo a(10);
                          Foo b(20);
                          Foo c = a.opeator+(b);
                          Foo d = a + b;

                          You must try to run this second example. Foo c = a.opeator+(b) is a valid c++ code and will compile just fine. b + c is provided for convenience which is automatically converted by compiler to b.operator+(c). -Saurabh

                          1 Reply Last reply
                          0
                          Reply
                          • Reply as topic
                          Log in to reply
                          • Oldest to Newest
                          • Newest to Oldest
                          • Most Votes


                          • Login

                          • Don't have an account? Register

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • World
                          • Users
                          • Groups