6.9 Operator overloading
Sometimes you want an object to act as if it was a string, an integer or some
other data type. It is especially interesting to be able to use the normal
operators on objects to allow short and readable syntax. In Pike, special
methods are called when an operator is used with an object. To some extent,
this is work in progress, but what has been done so far is very useful and
will not be subject to change.
The following table assumes that a and b are objects and shows what will be
evaluated if you use that particular operation on an object. Note that some
of these operators, notably == and ! have default behavior
which will be used if the corresponding method is not defined in the object.
Other operators will simply fail if called with objects. Refer to
chapter 5 "Operators" for information on which operators can operate on objects
without operator overloading.
Operation | | Will call | | Or |
a+b | | a->`+(b) | | b->``+(a) |
a+b+c+d | | a->`+(b,c,d) | | (b->(a))+c+d |
a-b | | a->`-(b) | | b->``-(a) |
a&b | | a->`&(b) | | b->``&(a) |
a|b | | a->`|(b) | | b->``|(a) |
a^b | | a->`^(b) | | b->``^(a) |
a>>b | | a->`>>(b) | | b->``>>(a) |
a<<b | | a->`<<(b) | | b->``<<(a) |
a*b | | a->`*(b) | | b->``*(a) |
a*b*c*d | | a->`*(b,c,d) | | b->`*(a)*c*d |
a/b | | a->`/(b) | | b->``/(a) |
a%b | | a->`%(b) | | b->``%(a) |
~a | | a->`~() | | |
a==b | | a->`==(b) | | b->`==(a) |
a!=b | | !( a->`==(b) ) | | !( b->`==(a) ) |
a<b | | a->`<(b) | | b->`>(a) |
a>b | | a->`>(b) | | b->`<(a) |
a<=b | | !( b->`>(a) ) | | !( a->`<(b) ) |
a>=b | | !( b->`<(a) ) | | !( a->`>(b) ) |
(int)a | | a->cast("int") | | |
!a | | a->`!() | | |
if(a) { ... } | | !( a->`!() ) | | |
a[b] | | a->`[](b) | | |
a[b]=c | | a->`[]=(b,c) | | |
a->foo | | a->`->("foo") | | |
a->foo=b | | a->`->=("foo",b) | | |
sizeof(a) | | a->_sizeof() | | |
indices(a) | | a->_indices() | | |
values(a) | | a->_values() | | |
a(b) | | a->`()(b) | | |
|
Here is a really silly example of a program that will write 10
to stdout when executed.
#!/usr/local/bin/pike
class three {
int `+(int foo) { return 3+foo; }
};
int main()
{
write(sprintf("%d\n",three()+7));
}
It is important to know that some optimizations are still performed even
when operator overloading is in effect. If you define a multiplication operator
and multiply your object with one, you should not be surprised if the
multiplication operator is never called. This might not always be what you
expect, in which case you are better off not using operator overloading.