Overloading binary operators. Operator overloading +, –, *, /, %. Nesting arbitrary logic on overload
Before studying this topic, it is recommended that you familiarize yourself with the following topic:
Contents
- 1. Features of overloading binary operators
- 2. Overloading of binary operators +, –, *, /. Example
- 3. Features of operator overloading +=, -=, *=, /=, %=
- 4. An example of overloading the % operator. Determining the arithmetic mean of two arrays. Programming arbitrary logic when overloading operators
- Related topics
Search other resources:
1. Features of overloading binary operators
C# allows you to overload the following binary operators:
- + – addition (a + b);
- – – substraction (a – b);
- * – multiplication (a * b);
- / – division (a / b);
- % – the operator for taking the remainder of division. Can be overloaded at its own discretion;
- & – bitwise logical “AND”;
- | – bitwise logical “OR”;
- ^ – bitwise addition modulo 2;
- <, > – comparison operators (less than, greater than). In a class, these operators are necessarily overloaded by a pair (both);
- <=, >= – comparison operators (less than or equal, greater than or equal). These operators are overloaded as a pair;
- ==, != – comparison operators (equal, not equal). Overloaded by a pair in class.
When overloading binary operators, a static method is created that takes 2 parameters. The type of these parameters is the type of the class that implements the method that overloads the operator.
In the most general case, the overload of a binary operator in a class named ClassName is of the form:
class ClassName { public static ClassName operator op(ClassName obj1, ClassName obj2) { // Actions to be taken when calling obj1 op obj2 // ... } }
here
- op – one of the standard binary operators that can be overloaded (+, -, ==, >, etc.);
- obj1 – an instance located to the left of the op operator;
- obj2 – the instance to the right of the op operator.
After overloading, instances of obj1 and obj2 can be combined with the op operator in a more visual way
obj1 op obj2
For example, if you overload the + operator, then the corresponding method call will be
obj1 + obj2
⇑
2. Overloading of binary operators +, –, *, /. Example
A Complex class is specified that defines a complex number. The class contains the minimum possible set of methods and properties for full functioning.
The Complex class redefines the +, -, *, / operators, which implement respectively addition, subtraction, multiplication, and division of two complex numbers.
using System; namespace ConsoleApp6 { class Complex { // Internal class fields private double re, im; // Constructor public Complex(double re, double im) { this.re = re; this.im = im; } // Internal field access properties public double Re { get { return re; } set { re = value; } } public double Im { get { return im; } set { im = value; } } // The operator method, which overloads the binary operator '+', // implements the addition of complex numbers. public static Complex operator+(Complex cm1, Complex cm2) { return new Complex(cm1.re + cm2.re, cm1.im + cm2.im); } // Operator method overloading binary operator '-', // implements subtraction of complex numbers public static Complex operator-(Complex cm1, Complex cm2) { return new Complex(cm1.re - cm2.re, cm1.im - cm2.im); } // Method overloading the '*' operator, // implements multiplication of complex numbers public static Complex operator*(Complex cm1, Complex cm2) { return new Complex(cm1.re * cm2.re - cm1.im * cm2.im, cm1.re * cm2.im + cm1.im * cm2.re); } // Operator overload '/' - division of complex numbers public static Complex operator/(Complex cm1, Complex cm2) { double denom = cm2.re * cm2.re + cm2.im * cm2.im; return new Complex((cm1.re * cm2.re + cm1.im * cm2.im) / denom, (cm1.im * cm2.re - cm1.re * cm2.im) / denom); } // Method that displays the state of the current instance public void Print(string msg) { Console.Write(msg + " => "); Console.Write(re); if (im >= 0) Console.Write("+"); Console.WriteLine(im.ToString() + "*j"); } } internal class Program { static void Main(string[] args) { // 1. Create 2 objects of type Complex Complex cm1 = new Complex(3, 5); Complex cm2 = new Complex(2, -4); // 2. Display objects cm1.Print("cm1"); cm2.Print("cm2"); // 3. Add objects Complex cm3; cm3 = cm1 + cm2; // a method is called that overloads the '+' operator cm3.Print("cm1 + cm2"); // 4. Subtract - calling the Complex.operator-() method (cm1 - cm2).Print("cm1-cm2"); // 5. Multiply cm3 = cm1 * cm2; cm3.Print("cm1 * cm2"); // 6. Divide cm3 = cm1 / cm2; cm3.Print("cm1 / cm2"); // 7. Usint operators +=, -=, *=, /= Complex cm4 = new Complex(1, 1); cm4 += cm1; // => cm4 = cm4 + cm1; cm4.Print("cm4"); Complex cm5 = new Complex(2, 3); cm5 *= cm2; // => cm5 = cm5 * cm2 cm5.Print("cm5"); Console.ReadKey(); } } }
Result
cm1 => 3+5*j cm2 => 2-4*j cm1 + cm2 => 5+1*j cm1-cm2 => 1+9*j cm1 * cm2 => 26-2*j cm1 / cm2 => -0.7+1.1*j cm4 => 4+6*j cm5 => 16-2*j
⇑
3. Features of operator overloading +=, -=, *=, /=, %=
Shorthand assignment operators +=, -=, *=, /=, %= and others like them are considered overloaded as soon as their corresponding operators +, –, *, /, % and others are overloaded.
Using the Point class as an example, the + and – operators are overloaded. It then shows the invocation of the corresponding +=, -= operators for instances of the Point class.
The overloaded + and – operators perform addition and subtraction of point coordinates.
using System; namespace ConsoleApp6 { // A class that describes a point on the coordinate plane class Point { // Internal variables private int x, y; // Constructor public Point(int x, int y) { this.x = x; this.y = y; } // Coordinate access properties public int X { get { return x; } } public int Y { get { return y; } } // Method that prints the current x, y values public void Print(string msg) { Console.WriteLine(msg + " => " + "( " + x + "; " + y + ")"); } // Overloaded operators '+' та '-' public static Point operator+(Point p1, Point p2) { return new Point(p1.x + p2.x, p1.y + p2.y); } public static Point operator-(Point p1, Point p2) { return new Point(p1.x - p2.x, p1.y - p2.y); } } internal class Program { static void Main(string[] args) { // 1. Create 2 instances of Point class Point pt1 = new Point(3, 8); Point pt2 = new Point(4, 9); // 2. Use the += operator to calculate the sum of points pt1 and pt2 pt1 += pt2; // => pt1 = pt1 + pt2; - is performed: pt1 = Point.operator+(pt1, pt2) pt1.Print("pt1"); // 3. Call the operator -= to calculate difference pt2 = pt2 - pt1; pt2 -= pt1; // pt2 = Point.operator(pt2, pt1); pt2.Print("pt2"); Console.ReadKey(); } } }
After overloading the + and – operators in the Point class, the corresponding += and -= operators in strings are called in the main() function
pt1 += pt2; pt2 -= pt1;
After execution, the program produces the following result
pt1 => ( 7; 17) pt2 => ( -3; -8)
⇑
4. An example of overloading the % operator. Determining the arithmetic mean of two arrays. Programming arbitrary logic when overloading operators
Methods overloaded by operators can contain code that implements any actions. The code of an overloaded method does not have to match the purpose of the operator that the method overloads.
The % operator defines the remainder of a division of integer values. However, in our case, a different logic is implemented. The arithmetic mean of two operands, which are arrays of the ArrayDouble type, is determined. This example is for demonstration purposes only and shows how the logic of operator methods can be programmed in different ways.
Note that the operator method operator%() returns double, not ArrayDouble.
using System; namespace ConsoleApp6 { // Array of floating point numbers class ArrayDouble { private double[] AD; // Constructor public ArrayDouble(double[] _AD) { // Copying AD = _AD AD = new double[_AD.Length]; for (int i = 0; i < AD.Length; i++) AD[i] = _AD[i]; } // Method that outputs array AD public void Print(string msg) { Console.Write(msg + " => "); for (int i = 0; i < AD.Length; i++) Console.Write(AD[i] + " "); Console.WriteLine(); } // Overloading of operator %. // Determination of the arithmetic mean of two operand arrays. // Note: the method returns double and not ArrayDouble public static double operator%(ArrayDouble AD1, ArrayDouble AD2) { // 1. Calculate the sum of array elements double res = 0; for (int i = 0; i < AD1.AD.Length; i++) res += AD1.AD[i]; for (int i = 0; i < AD2.AD.Length; i++) res += AD2.AD[i]; // 2. Return the arithmetic mean return res / (AD1.AD.Length + AD2.AD.Length); } } internal class Program { static void Main(string[] args) { // 1. Create 2 arrays of double[] type double[] A1 = { 2.4, 3.1, 0.8, -2.2, 0.9, 11.6 }; double[] A2 = { 3.8, 11.7, -4.4, 0.8 }; // 2. Create 2 instances based on arrays ArrayDouble AD1 = new ArrayDouble(A1); ArrayDouble AD2 = new ArrayDouble(A2); // 3. Print arrays for control AD1.Print("AD1"); AD2.Print("AD2"); // 4. Use the overloaded % operator to calculate the arithmetic mean. double average = AD1 % AD2; Console.WriteLine("AD1 % AD2 = {0:f3}", average); Console.ReadKey(); } } }
Result
AD1 => 2.4 3.1 0.8 -2.2 0.9 11.6 AD2 => 3.8 11.7 -4.4 0.8 AD1 % AD2 = 2.850
⇑
Related topics
- Operators overloading. General information. Overloading of unary operators –, !, ++, —
- Overloading comparison operators ==, !=, <, >, <=, >=. Overloading boolean bitwise operators &, |, ^
⇑