Operator overloading is a type of compile-time polymorphism. In this process, the compiler determines which function to execute from a group of functions with the same name based on the types of parameters involved.
In D language, we can overload binary operators by defining special methods within our custom type.
The method name corresponds to the overloaded operator. By overloading binary operators, we can make the operators behave for our defined struct as per our requirements.
opBinary
and opCmp
methodsThe opBinary
method is a generic function that takes a string op
representing the operator and is used to overload binary operators like +
, -
, *
, =
etc. In the opBinary
method, the condition if (op == "...")
is used to specify which operator is being overloaded. While opCmp
is used to overload comparison operators like <
, <=
, ==
, !=
, >=
, >
. This method generally returns 0
for equality, a negative value for less than, and a positive value for greater than.
Binary operators are broadly divided into four categories:
Arithmetic operators
Assignment operators
Bitwise operators
Relational operators
Following are the code examples for each type of binary operator.
import std.stdio;struct Vector {int x, y;// Overloading the + operatorVector opBinary(string op)(Vector other) if (op == "+") {return Vector(x + other.x, y + other.y);}}void main() {Vector v1 = Vector(1, 2);Vector v2 = Vector(3, 4);Vector v3 = v1 + v2;// Now v3.x will be 1 + 3 = 4, v3.y will be 2 + 4 = 6writeln("(", v3.x, ", ", v3.y, ")");}
Line 1: A package for input-output operations is imported.
Line 2: A struct Vector
is defined as having two member variables.
Lines 5–7: The +
operator is overloaded using the opBinary
method. This function takes another Vector
as an argument and returns a new Vector
with the added components.
Lines 11–12: Two Vector
objects are declared and initialized.
Line 13: Another Vector
object is declared that is initialized using the overloaded +
operator.
Line 15: The output is displayed.
import std.stdio;struct Vector {int x, y;// Overloading the assignment operatorvoid opBinary(string op)(string newValue) if (op == "=") {value = newValue;}}void main() {Vector v1 = Vector(1, 9);Vector v2 = v1;writeln("(", v2.x, ", ", v2.y, ")");}
Line 1: A package for input-output operations is imported.
Line 2: A struct Vector
is defined as having two member variables.
Lines 5–7: The =
operator is overloaded using the opBinary
method. This function takes another Vector
as an argument and returns the result of comparison.
Line 11: A Vector
object is declared and initialized.
Line 12: Another Vector
object is declared and initialized with the overloaded assignment operator.
Line 13: The result of the assignment is displayed.
import std.stdio;struct Bitwise {int bits;Bitwise opBinary(string op)(Bitwise other) if (op == "&") {return Bitwise(bits & other.bits);}}void main() {Bitwise b1 = Bitwise(5); // 5 in integer = 0101 in binaryBitwise b2 = Bitwise(3); // 3 in integer = 0011 in binaryBitwise result = b1 & b2; // 0001 in binary = 1 in integerwriteln("Result: ", result.bits);}
Line 1: A package for input-output operations is imported.
Line 2: A struct Bitwise
is defined as having an integer member variable.
Lines 4–6: The &
operator is overloaded using the opBinary
method. This function takes another Bitwise
object as an argument and returns the result of bitwise and
.
Lines 10–11: Two Bitwise
objects are declared and initialized.
Line 12: The overloaded relational operator &
is called, and the result is stored in another Bitwise
object.
Line 13: The result of the bitwise and
is displayed.
import std.stdio;struct Vector {int x, y;// Overloading the relational operator ">"int opCmp(Vector other) {if (x == other.x && y == other.y) return 0;return (x > other.x && y > other.y) ? 1 : -1;}}void main() {Vector v1 = Vector(1, 2);Vector v2 = Vector(3, 4);bool result = v1 > v2;writeln("Result: ", result);}
Line 1: A package for input-output operations is imported.
Line 2: A struct Vector
is defined as having two member variables.
Lines 5–8: The >
operator is overloaded using the opCmp
method. This function takes another Vector
as an argument and returns the result of comparison.
Lines 12–13: Two Vector
objects are declared and initialized.
Line 14: The overloaded relational operator >
is called, and the result is stored in a variable.
Line 15: The result of the comparison is displayed.
In summary, overloading binary operators in D enhances code expressiveness and flexibility, enabling developers to create more intuitive and readable programs. This feature, demonstrated in this answer in terms of syntax and importance, provides an amazing tool for achieving polymorphism and adhering to object-oriented programming principles in the D language.
Free Resources