Operator overloading allows the programmer to define how operators like , , , and should work with custom data types. This is useful because it allows you to use the familiar syntax of operators with your own data types, making your code more readable and intuitive.
There are two types of assignment operator overloading: identity assignment and non-identity assignment.
Identity assignment refers to when the assignment operator is used to assign one object to another object of the same type, while non-identity assignment refers to when the assignment operator is used to assign a value of a different type to an object.
To overload the assignment operator in a Dlang struct, you can define a member function called opAssign() that takes another object (right argument) as its parameter. This function should be defined inside the struct itself, like this:
struct MyStruct {void opAssign(MyStruct obj) { // Identity assignment// Statements}void opAssign(int num) { // Non Identity assignment// Statements}}
When you use the = operator to assign one MyStruct
object to another, the opAssign()
function will be called automatically to perform the assignment. You can also define other overloads of the opAssign()
function to handle non-identity assignments, such as assigning an int
value to a MyStruct
object.
The following example shows a struct called Node
that has two integer fields, num1
and num2
.
import std.stdio;struct Node {int num1;int num2;// Overload the assignment operator for Node objectsvoid opAssign(Node other) {// Add the values of the other Node to this onethis.num1 += other.num1;this.num2 += other.num2;}// Overload the assignment operator for int valuesvoid opAssign(int value) {// Set both fields to the given valuethis.num1 = value;this.num2 = value;}}void main() {Node Node1;Node1.num1 = 5;Node1.num2 = 10;writeln("Nodes1 values are (num1, num2): ", Node1.num1, " ", Node1.num2);Node Node2;Node2 = Node1; // identity assignmentwriteln("Nodes2 values are (num1, num2): ", Node2.num1, " ", Node2.num2);Node Node3;Node3 = 20; // Non-identity assignmentwriteln("Nodes3 values are (num1, num2): ", Node3.num1, " ", Node3.num2);}
This code defines a struct
called Node
with two integer fields and two versions of the opAssign()
function for overloading the assignment operator. The main()
function creates three Node
objects and assigns values using the overloaded operator in different ways.
The image below shows the behavior of the assignment operator when it is overloaded.
In classes only non-identity assignment is allowed, we cannot overload the assignment operator for identity assignment, because classes have reference semantics and the behavior of the assignment operator is not overridable.
To understand assignment operator overloading, consider a class called C
that has two integer fields, num
and square
. The following code provides an example of how to overload the assignment operator in this class.
import core.stdc.stdio;import std.stdio;class C { // Create classint num;int square;void opAssign(int a) // Create opAssign method{ // to overload assignment operatorthis.num=a;this.square=a*a;}}int main(){C obj1= new C;obj1.num=5;obj1.square=obj1.num*obj1.num; // Create class object and assign value to itwriteln("Obj1 num value: ",obj1.num ,", Obj1 num square: ", obj1.square);obj1=20; // Assign value using assignment operator overloadingwriteln("Obj1 num value: ",obj1.num ,", Obj1 num square: ", obj1.square);return 0;}
Line 4–13: We define class
named C
with two integers num
, square
and member function opAssign
from lines
Line 16–18: We create the class instance obj1
and assign value without overloading the assignment operator.
Line 20: We update the value of obj1
using the assignment overloading by calling opAssign()
the method in the background.
Free Resources