Polymorphism |
---|
Ad hoc polymorphism |
Parametric polymorphism |
Subtyping |
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.
Operator 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 a
, b
and c
of some user-defined type, such as matrices:
a + b * c
In a language that supports operator overloading, and with the usual assumption that the '*' operator has higher precedence than the '+' operator, this is a concise way of writing:
Add(a, Multiply(b, c))
However, the former syntax reflects common mathematical usage.
In this case, the addition operator is overloaded to allow addition on a user-defined type Time
in C++:
Timeoperator+(constTime&lhs,constTime&rhs){Timetemp=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;returntemp;}
Addition is a binary operation, which means it has two operands. In C++, the arguments being passed are the operands, and the temp
object is the returned value.
The operation could also be defined as a class method, replacing lhs
by the hidden this
argument; However, this forces the left operand to be of type Time
:
// The "const" right before the opening curly brace means that |this| is not modified.TimeTime::operator+(constTime&rhs)const{Timetemp=*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;returntemp;}
Note that a unary operator defined as a class method would receive no apparent argument (it only works from this
):
boolTime::operator!()const{returnhours==0&&minutes==0&&seconds==0;}
The less-than (<) operator is often overloaded to sort a structure or class:
classPair{public:booloperator<(constPair&p)const{if(x_==p.x_){returny_<p.y_;}returnx_<p.x_;}private:intx_;inty_;};
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.
Operator 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 <<
operator in C++ a<<b
shifts the bits in the variable a
left by b
bits if a
and b
are of an integer type, but if a
is an output stream then the above code will attempt to write a b
to the stream. Because operator overloading allows the original programmer to change the usual semantics of an operator and to catch any subsequent programmers by surprise, it is considered good practice to use operator overloading with care (the creators of Java decided not to use this feature, [3] although not necessarily for this reason).
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 a + b == b + a
) does not always apply; an example of this occurs when the operands are strings, since + is commonly overloaded to perform a concatenation of strings (i.e. "bird" + "song"
yields "birdsong"
, while "song" + "bird"
yields "songbird"
). A typical counter[ citation needed ] to this argument comes directly from mathematics: While + is commutative on integers (and more generally any complex number), it is not commutative for other "types" of variables. In practice, + is not even always associative, for example with floating-point values due to rounding errors. Another example: In mathematics, multiplication is commutative for real and complex numbers but not commutative in matrix multiplication.
A 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.
Operators | Not overloadable | Overloadable |
---|---|---|
New definable [4] | ||
Limited set |
|
The ALGOL 68 specification allowed operator overloading. [43]
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) opabs = (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:
priomax = 9; opmax = (int a, b) int: ( a>b | a | b ); op++ = ( refint a ) int: ( a +:= 1 );
Ada 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. [44]
Java language designers at Sun Microsystems chose to omit overloading. [45] [46] [47]
Python allows operator overloading through the implementation of methods with special names. [48] For example, the addition (+) operator can be overloaded by implementing the method obj.__add__(self, other)
.
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.
Microsoft 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:
multiinfix:<+>(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.
Templates are a feature of the C++ programming language that allows functions and classes to operate with generic types. This allows a function or class declaration to reference via a generic variable another different class without creating full declaration for each of these different classes.
Generic programming is a style of computer programming in which algorithms are written in terms of data types to-be-specified-later that are then instantiated when needed for specific types provided as parameters. This approach, pioneered in the programming language ML in 1973, permits writing common functions or data types that differ only in the set of types on which they operate when used, thus reducing duplicate code.
A method in object-oriented programming (OOP) is a procedure associated with an object, and generally also a message. An object consists of state data and behavior; these compose an interface, which specifies how the object may be used. A method is a behavior of an object parametrized by a user.
In computer programming, a function object is a construct allowing an object to be invoked or called as if it were an ordinary function, usually with the same syntax. In some languages, particularly C++, function objects are often called functors.
This is a list of operators in the C and C++ programming languages. All the operators listed exist in C++; the column "Included in C", states whether an operator is also present in C. Note that C does not support operator overloading.
In computer programming, the ternary conditional operator is a ternary operator that is part of the syntax for basic conditional expressions in several programming languages. It is commonly referred to as the conditional operator, conditional expression, ternary if, or inline if. An expression if a then b else c
or a ? b : c
evaluates to b
if the value of a
is true, and otherwise to c
. One can read it aloud as "if a then b otherwise c". The form a ? b : c
is the most common, but alternative syntax do exist; for example, Raku uses the syntax a ?? b !! c
to avoid confusion with the infix operators ?
and !
, whereas in Visual Basic .NET, it instead takes the form If(a, b, c)
.
ALGOL 68 is an imperative programming language that was conceived as a successor to the ALGOL 60 programming language, designed with the goal of a much wider scope of application and more rigorously defined syntax and semantics.
Short-circuit evaluation, minimal evaluation, or McCarthy evaluation is the semantics of some Boolean operators in some programming languages in which the second argument is executed or evaluated only if the first argument does not suffice to determine the value of the expression: when the first argument of the AND
function evaluates to false
, the overall value must be false
; and when the first argument of the OR
function evaluates to true
, the overall value must be true
.
In computer programming, operators are constructs defined within programming languages which behave generally like functions, but which differ syntactically or semantically.
In computer science, the Boolean is a data type that has one of two possible values which is intended to represent the two truth values of logic and Boolean algebra. It is named after George Boole, who first defined an algebraic system of logic in the mid 19th century. The Boolean data type is primarily associated with conditional statements, which allow different actions by changing control flow depending on whether a programmer-specified Boolean condition evaluates to true or false. It is a special case of a more general logical data type—logic does not always need to be Boolean.
In computer science, a relational operator is a programming language construct or operator that tests or defines some kind of relation between two entities. These include numerical equality and inequalities.
Barton–Nackman trick is a term coined by the C++ standardization committee to refer to an idiom introduced by John Barton and Lee Nackman as restricted template expansion.
The computer programming languages C and Pascal have similar times of origin, influences, and purposes. Both were used to design their own compilers early in their lifetimes. The original Pascal definition appeared in 1969 and a first compiler in 1970. The first version of C appeared in 1972.
The syntax of JavaScript is the set of rules that define a correctly structured JavaScript program.
A class in C++ is a user-defined type or data structure declared with any of the keywords class
, struct
or union
that has data and functions as its members whose access is governed by the three access specifiers private, protected or public. By default access to members of a C++ class declared with the keyword class
is private. The private members are not accessible outside the class; they can be accessed only through member functions of the class. The public members form an interface to the class and are accessible outside the class.
C++11 is a version of a joint technical standard, ISO/IEC 14882, by the International Organization for Standardization (ISO) and International Electrotechnical Commission (IEC), for the C++ programming language. C++11 replaced the prior version of the C++ standard, named C++03, and was later replaced by C++14. The name follows the tradition of naming language versions by the publication year of the specification, though it was formerly named C++0x because it was expected to be published before 2010.
A property, in some object-oriented programming languages, is a special sort of class member, intermediate in functionality between a field and a method. The syntax for reading and writing of properties is like for fields, but property reads and writes are (usually) translated to 'getter' and 'setter' method calls. The field-like syntax is easier to read and write than many method calls, yet the interposition of method calls "under the hood" allows for data validation, active updating, or implementation of what may be called "read-only fields".
ALGOL 68-R was the first implementation of the Algorithmic Language ALGOL 68.
The null coalescing operator is a binary operator that is part of the syntax for a basic conditional expression in several programming languages, such as : C# since version 2.0, Dart since version 1.12.0, PHP since version 7.0.0, Perl since version 5.10 as logical defined-or, PowerShell since 7.0.0, and Swift as nil-coalescing operator.
Concepts are an extension to the templates feature provided by the C++ programming language. Concepts are named Boolean predicates on template parameters, evaluated at compile time. A concept may be associated with a template, in which case it serves as a constraint: it limits the set of arguments that are accepted as template parameters.
{{cite web}}
: Check |url=
value (help)One of the nicest features of C++ OOP is that you can overload operators to handle objects of your classes (you can't do this in some other OOP-centric languages, like Java).