Operator overloading and *this

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • y-man

    #1

    Operator overloading and *this

    Hi,

    I am trying to get an overloaded operator to work inside the class it
    works on. The situation is something like this:


    main.cc:
    #include "object.hh"
    #include "somefile.h h"
    object obj, obj2 ;

    obj2 = obj.bla(25) ;



    object.hh:

    class object {
    public:
    object() {} ;

    void set_a(double num) {
    a = num ;
    }

    double get_a( void ) {
    return a;
    }

    bla(double num) {
    return (*this) + num
    }
    private:
    double a;

    } ;


    somefile.hh:
    #include "object.hh"
    object operator+ (double, object)

    somefile.cc:

    object operator+ (double a, object obj) {
    obj.set_a(obj.g et_a + a) ;
    }

    When I compile, I find out that the object does not know that the
    operator exists. Is there a way to make this work correctly?

  • mlimber

    #2
    Re: Operator overloading and *this

    On Mar 21, 11:48 am, "y-man" <ygra...@gmail. comwrote:
    Hi,
    >
    I am trying to get an overloaded operator to work inside the class it
    works on. The situation is something like this:
    >
    main.cc:
    #include "object.hh"
    #include "somefile.h h"
    object obj, obj2 ;
    >
    obj2 = obj.bla(25) ;
    >
    object.hh:
    >
    class object {
    public:
    object() {} ;
    >
    void set_a(double num) {
    a = num ;
    >
    }
    >
    double get_a( void ) {
    return a;
    >
    }
    >
    bla(double num) {
    return (*this) + num}
    >
    private:
    double a;
    >
    } ;
    >
    somefile.hh:
    #include "object.hh"
    object operator+ (double, object)
    >
    somefile.cc:
    >
    object operator+ (double a, object obj) {
    obj.set_a(obj.g et_a + a) ;
    >
    }
    >
    When I compile, I find out that the object does not know that the
    operator exists. Is there a way to make this work correctly?
    Include somefile.hh in object.hh before the definition of
    object::bla(), add to it an operator that takes an object and a double
    (in that order), and fix your syntax errors. BTW, you probably want
    the parameter to your function to be "const object&". See also this
    FAQ on posting code that doesn't work:



    Cheers! --M

    Comment

    • blangela

      #3
      Re: Operator overloading and *this

      On Mar 21, 8:48 am, "y-man" <ygra...@gmail. comwrote:
      Hi,
      >
      I am trying to get an overloaded operator to work inside the class it
      works on. The situation is something like this:
      >
      main.cc:
      #include "object.hh"
      #include "somefile.h h"
      object obj, obj2 ;
      >
      obj2 = obj.bla(25) ;
      >
      object.hh:
      >
      class object {
      public:
      object() {} ;
      >
      void set_a(double num) {
      a = num ;
      >
      }
      >
      double get_a( void ) {
      return a;
      >
      }
      >
      bla(double num) {
      return (*this) + num}
      >
      private:
      double a;
      >
      } ;
      >
      somefile.hh:
      #include "object.hh"
      object operator+ (double, object)
      >
      somefile.cc:
      >
      object operator+ (double a, object obj) {
      obj.set_a(obj.g et_a + a) ;
      >
      }
      >
      When I compile, I find out that the object does not know that the
      operator exists. Is there a way to make this work correctly?
      Here is something I threw together for my class as an introduction to
      operator overloading. It may be of benifit to you (please note that I
      will use the term "method" instead of "member function" at some points
      throughout the description below):

      Let us start with the assumption that we have created a class called
      BigInt which will represent an integer value internally as a string of
      digits. Therefore the number 123456789012345 would be represented
      internally within a BigInt object as the string "12345678901234 5".
      The advantage BigInt class has over built-in types like "long" and
      "int" is that the BigInt class is able to represent integers of almost
      limitless precision (limited only by the amount of memory available to
      the process running our application).

      If we supply BigInt class with a method to sum two BigInt objects, we
      might write some code that looks like this:

      BigInt A,B; // Instantiate 2 BigInt objects

      .... // A and B are assigned values here

      A.Add(B); // The Add method will sum A and B.

      The implementation for the Add() method might look like this:

      BigInt & BigInt::Add( const BigInt & RHS)
      {
      /* In here is the code to sum the two BigInt objects (the BigInt
      object pointed to by the "this" pointer and the RHS BigInt object) */
      }

      There are at two problems with the solution described above. First,
      when we look at the line of code that invokes the Add method, we are
      not certain whether A is being added to B or if B is being added to A.
      The second problem is that the syntax used above means that our BigInt
      class is NOT a first rate data type. Instead, we would like to be
      able to write the following code:

      A += B; // Sum B into A

      If we were able to write our code in the manner shown in the statement
      above, we would be well on our way to making the BigInt class into a
      first rate data type!

      In order to write the code in the manner shown above, we must provide
      the compiler with a method (aka member function) or a global function
      that it may use to overload the "+=" operator. The compiler will
      cause this method or global function to be invoked whenever it
      encounters the "+=" operator with a BigInt object to the left of the
      operator and a BigInt object to the right of the operator. Supplying
      the C++ compiler with such a method or global function is called
      "overloadin g an operator".

      The method used to overload the "+=" operator discussed above would
      look like this:

      BigInt & BigInt::operato r += ( const BigInt & RHS)
      {
      /* Here we provide the code to sum together the two BigInt objects
      (the BigInt object pointed to by the "this" pointer and the RHS BigInt
      object) */
      }

      It is important to understand that the implementation of the method
      above would be exactly the same as the implementation would have been
      for the Add() method discussed above - except that the method would be
      called "operator +=" instead of "Add".

      We can invoke the "operator +=" method in exactly the same manner as
      we invoked the "Add" method above:

      A.operator +=(B); // Sum B into A

      Not that we would be likely do so! Calling our method "operator +="
      instead of "Add" causes the compiler to recognize that the "+="
      operator is now overloaded. Now, anytime the compiler encounters the
      "+=" operator with a BigInt operand on the left hand side of the
      operator and a BigInt operand on the right hand side of the operator,
      the compiler will invoke the "operator +=" method . Therefore, instead
      of invoking the method as shown in the program statement above, we
      should invoke it in the following manner:

      A += B; // Invokes the same method as: A.operator +=(B);

      Much better don't you agree! Now our BigInt class is a first rate
      data type!

      But what if we have the following program statements:

      BigInt A; // Instantiate a BigInt object
      long L = 10; // Instantiate a long object
      .... // A is assigned a value here
      A += L ; // What happens here?

      Will the above statement cause the "operator +=" method we discussed
      above to be invoked? Yes, but only if we provide the compiler with a
      way to convert L (which is a long) into a BigInt. In order to do
      this, we would need to provide the compiler with a conversion
      constructor that looks something like this:

      BigInt::BigInt( const long & L_value)
      {
      /* Convert the long L_value into a BigInt and assign it to the BigInt
      object pointed to by the "this" pointer. */
      }

      If we do not provide such a conversion constructor, the program
      statement:

      A += L; // What happens here?

      will cause a compile error unless we overload the "+=" operator a
      second time by providing the compiler the implementation for the
      following method:

      BigInt & BigInt::operato r += ( const long & RHS)
      {
      /* Here we provide the code to sum together the BigInt object and the
      long object (the BigInt object pointed to by the "this" pointer and
      the RHS long object) */
      }

      And if we wanted to code the following program statements as well:

      BigInt A; // Instantiate a BigInt object
      double d = 10.0; // Instantiate a double object
      .... // A is assigned a value here
      A += d ;

      Again, if we do not provide an appropriate conversion constructor, we
      would need to overload the "+=" operator a third time and provide the
      compiler with the implementation for the following method:

      BigInt & BigInt::operato r += ( const double & RHS)
      {
      /* Here we provide the code to sum together the BigInt object and the
      double object (the BigInt object pointed to by the "this" pointer and
      the RHS double object) */
      }

      Hopefully you are starting to see a pattern here. Now what if we want
      to code the following program statements:

      BigInt A; // Instantiate a BigInt objects
      double d = 10.0; // Instantiate a double object
      .... // A is assigned a value here
      d += A; // a double value to the left of the +=
      operator and
      // a BigInt value to the right of the +=
      operator

      You ask, what is the difference between the code segment above and the
      code segment previous to it? The difference is, that now, the double
      value is on the left hand side of the "+=" operator, where as in the
      previous example the double value was on the right hand side of the
      operator. Will the following method provide the required solution?

      BigInt & BigInt::operato r += ( const BigInt & RHS)
      {
      /* Here we provide the code to sum together the double object and the
      BigInt object (the double object pointed to by the "this" pointer and
      the RHS BigInt object) */
      }

      No! Why? Because a method of the BigInt class must be invoked with a
      BigInt object and not with a double object. Neither can we add a new
      method to the "double" class (programmers cannot augment the built-in
      classes). Therefore, in this case, we must overload the += operator as
      a global function. The following global function will work:

      double & operator += (double & LHS, const BigInt & RHS)
      {
      /* Here we provide the code to sum together the double object and
      the BigInt object (the LHS double object and the RHS BigInt object) */
      }

      Since the above function will need to access the private members of
      the RHS BigInt object in order to add the two objects together, the
      BigInt class will need to extend friendship to the above function. We
      say therefore that the above function needs to be a "friend
      function".

      Whether we use a method or a global function to overload an operator
      usually depends on the situation. Often either could actually be
      used, but one might be more preferable. Generally we prefer to use a
      global function over a method when overloading an operator, simply to
      limit the number of methods that have access to the private data of
      our class. If we overload an operator as a method, it is usually
      because the overloaded operator requires access to one or more of the
      private members of the class.

      This completes your introduction to operator overloading.

      I hope that clears up a few points.

      Bob L.

      Comment

      • y-man

        #4
        Re: Operator overloading and *this

        Thanks to botrh of you! I have made it working. Sorry for posting in a
        bad way and thanks for the manual.

        Comment

        Working...