Overloading normal functionality ???

S

sarathy

Hi all,
I just wanted to know if it is possible to overload the
original meaning of operators. I read that it is not possible to
change the operator precedence by using operator overloading. Other
than that i think that the operator functionality can be overloaded.
But in the following code, the operator + has been overloaded on type
int. But it does'nt seem to work as the operator fn was not invoked.

In the following code,

# include <iostream>


using namespace std;



namespace blackbox
{
class A
{
public:
int a;
int operator *(int a);
};



int A::eek:perator * (int b)
{
return a+b;
}
}



int main()
{
using namespace blackbox;



int a=10;
int b=20;


int c=a*b;


cout << c << endl;



return 0;
}

OUTPUT:
---------------
200


Thanks and regards,
Sarathy
 
X

xiaohuamao

sarathy 写é“:
Hi all,
I just wanted to know if it is possible to overload the
original meaning of operators. I read that it is not possible to
change the operator precedence by using operator overloading. Other
than that i think that the operator functionality can be overloaded.
But in the following code, the operator + has been overloaded on type
int. But it does'nt seem to work as the operator fn was not invoked.

In the following code,

# include <iostream>


using namespace std;



namespace blackbox
{
class A
{
public:
int a;
int operator *(int a);
};



int A::eek:perator * (int b)
{
return a+b;
}

The operator you overloaded has a two parameters, one of the type A and
the other of type int. To overload the operator * for two ints, you
should use int operator * (const int &, const int &) instead.
 
S

Sumit RAJAN

sarathy said:
Hi all,
I just wanted to know if it is possible to overload the
original meaning of operators. I read that it is not possible to
change the operator precedence by using operator overloading. Other
than that i think that the operator functionality can be overloaded.
But in the following code, the operator + has been overloaded on type
int. But it does'nt seem to work as the operator fn was not invoked.




In the following code,

# include <iostream>


using namespace std;



namespace blackbox
{
class A
{
public:
int a;
int operator *(int a);
};



int A::eek:perator * (int b)
{
return a+b;
}
}



int main()
{
using namespace blackbox;



int a=10;
int b=20;


int c=a*b;


cout << c << endl;



return 0;
}

OUTPUT:

I'm not sure I fully understand what you're after. :).


# include <iostream>

namespace blackbox
{
class A
{
int a;
public:
A():a(0) {}
A(int val): a(val) {}
friend int operator * (const A& lhs, const A& rhs);

};

int operator * (const A& lhs, const A& rhs)
{
return lhs.a + rhs.a;
}
}


int main()
{
using namespace blackbox;

A a = 10;
A b = 20;

int c = a * b;

std::cout << c << std::endl;

return 0;
}

Regards,
Sumit.
 
X

xiaohuamao

#include <iostream>

namespace blackbox
{
class A
{
public:
A(int i): a(i) {}
int a;
int operator *(int a);
};


int A::eek:perator * (int b)
{
return a+b;
}
}


int main()
{
using namespace blackbox;

A a(10);
int b=20;

//This is the operator you overloaded, one of type A, the other of
type int.
int c=a*b;
cout << c << endl;

return 0;
}
 
J

John Carson

sarathy said:
Hi all,
I just wanted to know if it is possible to overload the
original meaning of operators. I read that it is not possible to
change the operator precedence by using operator overloading. Other
than that i think that the operator functionality can be overloaded.
But in the following code, the operator + has been overloaded on type
int. But it does'nt seem to work as the operator fn was not invoked.

In the following code,

# include <iostream>


using namespace std;



namespace blackbox
{
class A
{
public:
int a;
int operator *(int a);
};



int A::eek:perator * (int b)
{
return a+b;
}
}



int main()
{
using namespace blackbox;



int a=10;
int b=20;


int c=a*b;


cout << c << endl;



return 0;
}

OUTPUT:


You have defined operator* as a member variable of A, yet you do not have an
A object as your left-hand operand, so this could not possibly work.

Give A a constructor:

A(int x) : a(x)
{}

and then try:

A a(10);
int c = a*20;

Note that you cannot overload operators to work solely on built-in types
like ints. You can, however, overload binary operators to operate on a
mixture of user defined and built-in types. These don't have to be member
functions (and cannot be if the int is the left hand operand), e.g.,

struct S
{};

// non-member operator
int operator*(int lhs, const S&rhs)
{
return lhs+5;
}


int main()
{
S s;
int x = 8*s;
cout << x << endl;
return 0;
}

Incidentally, stop naming everything a or b. You are only confusing
yourself.
 
S

sarathy

Hi,
Note that you cannot overload operators to work solely on built-in types
like ints.

With member Operator Functions [ OF ] i understand it is not
possible to overload only built in type operands, because the member OF
requires an object to invoke it.
But this is not the case with a global and friend operator
functions. They dont need an object to operate upon. They just operate
on the args provided. I am sure that operator functions can be made
global, so that other classes can utilize them.

Hence an operator functions such as

Files operator + (Files f1, Files f2)
{
Files f = f1.getCount() + f2.getCount();
return f;
}

can surely exist as a global/friend OF and will be invoked by a line
as

Files f1(10), f2(20, f3;
f3 = f1+f2;

If the compiler can match the line f1+f2 to the global operator
function above correctly, then why is it not possible for a similar
match involvng only primitives ?

Is it a restriction in the compiler or am i going wrong anywhere ??

2. What does the following constructor do ??

A(int x, int y, int z):a(x),b(y),c(z) {}

I probably guess that it initializes its member variables. But i
remember that such a syntax is being used by a subclass constructor to
pass args to a superclass constructor. If so what happens if class A
had a superclass with names a, b and c AND class A with data members
a,b and c.

What will be the result ??

Regards,
Sarathy
 
K

Kai-Uwe Bux

sarathy said:
Hi,
Note that you cannot overload operators to work solely on built-in types
like ints.

With member Operator Functions [ OF ] i understand it is not
possible to overload only built in type operands, because the member OF
requires an object to invoke it.
But this is not the case with a global and friend operator
functions. They dont need an object to operate upon. They just operate
on the args provided. I am sure that operator functions can be made
global, so that other classes can utilize them.

Hence an operator functions such as

Files operator + (Files f1, Files f2)
{
Files f = f1.getCount() + f2.getCount();
return f;
}

can surely exist as a global/friend OF and will be invoked by a line
as

Files f1(10), f2(20, f3;
f3 = f1+f2;

If the compiler can match the line f1+f2 to the global operator
function above correctly, then why is it not possible for a similar
match involvng only primitives ?

Because the standard says so: built-in operators take only operands with
non-class type, and operator overload resolution occurs only when an
operand expression originally has class or enumeration type, operator
overload resolution can resolve to a built-in operator only when an operand
has a class type that has a user-defined conversion to a non-class type
appropriate for the operator, or when an operand has an enumeration type
that can be converted to a type appropriate for the operator. [from 13.6/1]

Is it a restriction in the compiler or am i going wrong anywhere ??

2. What does the following constructor do ??

A(int x, int y, int z):a(x),b(y),c(z) {}

I probably guess that it initializes its member variables. But i
remember that such a syntax is being used by a subclass constructor to
pass args to a superclass constructor. If so what happens if class A
had a superclass with names a, b and c AND class A with data members
a,b and c.

What will be the result ??

Did you try?



Best

Kai-Uwe Bux
 
S

sarathy

Hi,
Because the standard says so: built-in operators take only operands with
non-class type, and operator overload resolution occurs only when an
operand expression originally has class or enumeration type, operator
overload resolution can resolve to a built-in operator only when an operand
has a class type that has a user-defined conversion to a non-class type
appropriate for the operator, or when an operand has an enumeration type
that can be converted to a type appropriate for the operator. [from 13.6/1]

Can i take this stmt this way.

1. When the operands to a builtin operator are primitives [non-class
type], the operator's orignial meaning will be used.

2. When the operands to a builting operator are class type or
enumeration, then the compiler will search for the operator functions
corresponding to the class/enum. Hence the overloaded meaning of the
operator will be used.
Did you try?

Yes. The thing is that it was initializing the derived class data
members first, before going for the base class constructor
initialization. But when the derived class member variables were
removed the base constructors are initialized correctly.

Can you explain the reason for this behaviour?

Regards,
Sarathy
 
K

Kai-Uwe Bux

sarathy said:
Hi,
Because the standard says so: built-in operators take only operands with
non-class type, and operator overload resolution occurs only when an
operand expression originally has class or enumeration type, operator
overload resolution can resolve to a built-in operator only when an
operand has a class type that has a user-defined conversion to a
non-class type appropriate for the operator, or when an operand has an
enumeration type that can be converted to a type appropriate for the
operator. [from 13.6/1]

Can i take this stmt this way.

1. When the operands to a builtin operator are primitives [non-class
type], the operator's orignial meaning will be used.

2. When the operands to a builting operator are class type or
enumeration, then the compiler will search for the operator functions
corresponding to the class/enum. Hence the overloaded meaning of the
operator will be used.

It's a little more complicated: overload resolution tries to find what is
considered a "best match". Now, the precise rules are in the standard, and
I just stay away from writing code that requires me to know the details.
Fortunately, that is easy.
Yes. The thing is that it was initializing the derived class data
members first, before going for the base class constructor
initialization. But when the derived class member variables were
removed the base constructors are initialized correctly.

Can you explain the reason for this behaviour?

Not without seeing the code. Post a minimal, complete example that
illustrates your observation.


Best

Kai-Uwe Bux
 
J

John Carson

sarathy said:
2. What does the following constructor do ??

A(int x, int y, int z):a(x),b(y),c(z) {}

I probably guess that it initializes its member variables. But i
remember that such a syntax is being used by a subclass constructor to
pass args to a superclass constructor. If so what happens if class A
had a superclass with names a, b and c AND class A with data members
a,b and c.

What will be the result ??

Sensible people don't write classes like that.

I believe the answer is that the member a in the derived class will hide the
name of the base class, so you won't be able to call the base class
constructor (the default constructor, if any, will be called for the base
class). You could work around this by using the fully qualified name of the
base class, e.g., ::a, if the base class is in the global namespace:

A(int x, int y, int z):a(x),b(y),c(z), ::a(y) {}
 
M

Marcus Kwok

xiaohuamao said:
To overload the operator * for two ints, you
should use int operator * (const int &, const int &) instead.

You cannot overload operators for primitive types.
 

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

Members online

Forum statistics

Threads
474,266
Messages
2,571,075
Members
48,772
Latest member
Backspace Studios

Latest Threads

Top