Operator overloading and *this

Y

y-man

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.hh"
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.get_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?
 
M

mlimber

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.hh"
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.get_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:

http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.8

Cheers! --M
 
B

blangela

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.hh"
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.get_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 "123456789012345".
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
"overloading an operator".

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

BigInt & BigInt::eek:perator += ( 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::eek:perator += ( 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::eek:perator += ( 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::eek:perator += ( 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.
 
Y

y-man

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

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

operator = overloading... 12
operator overloading 6
operator overloading 9
overloading operator-> 0
Overloading reference operator 22
and operator overloading 0
Overloading operator-> 9
Operator overloading 6

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top