Operator overloading
In computer programming, operator overloading, sometimes termed operator ad hoc polymorphism, is a specific case of polymorphism, where different operators have different implementations depending on their arguments. Operator overloading is generally defined by a programming language, a programmer, or both. RationaleOperator overloading is syntactic sugar, and is used because it allows programming using notation nearer to the target domain[1] and allows user-defined types a similar level of syntactic support as types built into a language. It is common, for example, in scientific computing, where it allows computing representations of mathematical objects to be manipulated with the same syntax as on paper. Operator overloading does not change the expressive power of a language (with functions), as it can be emulated using function calls. For example, consider variables
In a language that supports operator overloading, and with the usual assumption that the
However, the former syntax reflects common mathematical usage. ExamplesIn this case, the addition operator is overloaded to allow addition on a user-defined type Time operator+(const Time& lhs, const Time& rhs) {
Time temp = lhs;
temp.seconds += rhs.seconds;
temp.minutes += temp.seconds / 60;
temp.seconds %= 60;
temp.minutes += rhs.minutes;
temp.hours += temp.minutes / 60;
temp.minutes %= 60;
temp.hours += rhs.hours;
return temp;
}
Addition is a binary operation, which means it has two operands. In C++, the arguments being passed are the operands, and the The operation could also be defined as a class method, replacing // The "const" right before the opening curly brace means that |this| is not modified.
Time Time::operator+(const Time& rhs) const {
Time temp = *this; // |this| should not be modified, so make a copy.
temp.seconds += rhs.seconds;
temp.minutes += temp.seconds / 60;
temp.seconds %= 60;
temp.minutes += rhs.minutes;
temp.hours += temp.minutes / 60;
temp.minutes %= 60;
temp.hours += rhs.hours;
return temp;
}
Note that a unary operator defined as a class method would receive no apparent argument (it only works from bool Time::operator!() const {
return hours == 0 && minutes == 0 && seconds == 0;
}
The less-than (<) operator is often overloaded to sort a structure or class: class Pair {
public:
bool operator<(const Pair& p) const {
if (x_ == p.x_) {
return y_ < p.y_;
}
return x_ < p.x_;
}
private:
int x_;
int y_;
};
Like with the previous examples, in the last example operator overloading is done within the class. In C++, after overloading the less-than operator (<), standard sorting functions can be used to sort some classes. CriticismsOperator overloading has often been criticized[2] because it allows programmers to reassign the semantics of operators depending on the types of their operands. For example, the use of the Another, more subtle, issue with operators is that certain rules from mathematics can be wrongly expected or unintentionally assumed. For example, the commutativity of + (i.e. that CatalogA classification of some common programming languages is made according to whether their operators are overloadable by the programmer and whether the operators are limited to a predefined set.
Timeline of operator overloading1960sThe ALGOL 68 specification allowed operator overloading.[44] Extract from the ALGOL 68 language specification (page 177) where the overloaded operators ¬, =, ≠, and abs are defined: 10.2.2. Operations on Boolean Operands a) op ∨ = (bool a, b) bool:( a | true | b ); b) op ∧ = (bool a, b) bool: ( a | b | false ); c) op ¬ = (bool a) bool: ( a | false | true ); d) op = = (bool a, b) bool:( a∧b ) ∨ ( ¬b∧¬a ); e) op ≠ = (bool a, b) bool: ¬(a=b); f) op abs = (bool a)int: ( a | 1 | 0 ); Note that no special declaration is needed to overload an operator, and the programmer is free to create new operators. For dyadic operators their priority compared to other operators can be set: prio max = 9; op max = (int a, b) int: ( a>b | a | b ); op ++ = ( ref int a ) int: ( a +:= 1 ); 1980sAda supports overloading of operators from its inception, with the publication of the Ada 83 language standard. However, the language designers chose to preclude the definition of new operators. Only extant operators in the language may be overloaded, by defining new functions with identifiers such as "+", "*", "&" etc. Subsequent revisions of the language (in 1995 and 2005) maintain the restriction to overloading of extant operators. In C++, operator overloading is more refined than in ALGOL 68.[45] 1990sJava language designers at Sun Microsystems chose to omit overloading.[46][47][48] Python allows operator overloading through the implementation of methods with special names.[49] For example, the addition (+) operator can be overloaded by implementing the method Ruby allows operator overloading as syntactic sugar for simple method calls. Lua allows operator overloading as syntactic sugar for method calls with the added feature that if the first operand doesn't define that operator, the method for the second operand will be used. 2000sMicrosoft added operator overloading to C# in 2001 and to Visual Basic .NET in 2003. Scala treats all operators as methods and thus allows operator overloading by proxy. In Raku, the definition of all operators is delegated to lexical functions, and so, using function definitions, operators can be overloaded or new operators added. For example, the function defined in the Rakudo source for incrementing a Date object with "+" is: multi infix:<+>(Date:D $d, Int:D $x) {
Date.new-from-daycount($d.daycount + $x)
}
Since "multi" was used, the function gets added to the list of multidispatch candidates, and "+" is only overloaded for the case where the type constraints in the function signature are met. While the capacity for overloading includes +, *, >=, the postfix and term i, and so on, it also allows for overloading various brace operators: "[x, y]", "x[y]", "x{y}", and "x(y)". Kotlin has supported operator overloading since its creation. See also
References
|
Portal di Ensiklopedia Dunia