Discussion on overload operator in structure

Keywords: C++

Discussion on overload operator in structure

1. Function of overloaded operator

Use overloaded operators instead of member functions to complete a series of tasks for variables of structure type. Of course, we can use member functions to accomplish these tasks directly, but we can use them without overloading operators.
Take an intuitive example: when implementing high-precision addition and subtraction, if you can directly use c = a + b c=a+b c=a+b means high-precision addition. Is it better than c = a d d ( a , b ) c=add(a,b) How intuitive is c=add(a,b)?

2. Principles of overloading operators

When the overloaded operator function is defined inside the class, the number of parameters of the operator is one less than the number of operands required by the specific overloaded operator, because a hidden parameter * this is used as the left operand (the first operand).
When the overloaded operator function is defined outside the class, the number of parameters is the same as the number of operands required by the specific overloaded operator.

sturct BigInteger{
	typedef unsigned long long LL;
    static const int BASE = 100000000;
    static const int WIDTH = 8;
    vector<int> s;
	BigInteger operator + (const BigInteger& b) const {
	    BigInteger c; c.s.clear();
	    for (int i = 0, g = 0; ; i++) {
	        if (g == 0 && i >= s.size() && i >= b.s.size()) break;
	        int x = g;
	        if (i < s.size()) x += s[i];
	        if (i < b.s.size()) x += b.s[i];
	        c.s.push_back(x % BASE);
	        g = x / BASE;
	    }
	    return c;
	}
}

In the above code, the overloaded function is defined inside the class, so you only need to pass in one parameter in the function s [ i ] s[i] s[i] represents the of the current object s [ i ] s[i] s[i].

typedef unsigned long long LL;
static const int BASE = 100000000;
static const int WIDTH = 8;
vector<int> s;
BigInteger operator + (const BigInteger& a const BigInteger& b) const {
    BigInteger c; c.s.clear();
	for (int i = 0, g = 0; ; i++) {
	    if (g == 0 && i >= a.s.size() && i >= b.s.size()) break;
	    int x = g;
	    if (i < a.s.size()) x += a.s[i];
	    if (i < b.s.size()) x += b.s[i];
	    c.s.push_back(x % BASE);
	    g = x / BASE;
	}
	return c;
}

This is the code defined outside the class.

3. The most important consideration of overloaded operators is the problem of parameters and return values

Take the code defined inside the class as an example

sturct BigInteger{
	typedef unsigned long long LL;
    static const int BASE = 100000000;
    static const int WIDTH = 8;
    vector<int> s;
	BigInteger operator + (const BigInteger& b) const {
	    BigInteger c; c.s.clear();
	    for (int i = 0, g = 0; ; i++) {
	        if (g == 0 && i >= s.size() && i >= b.s.size()) break;
	        int x = g;
	        if (i < s.size()) x += s[i];
	        if (i < b.s.size()) x += b.s[i];
	        c.s.push_back(x % BASE);
	        g = x / BASE;
	    }
	    return c;
	}
	BigInteger& operator = (long long num) {
        s.clear();
        do {
            s.push_back(num % BASE);
            num /= BASE;
        } while (num > 0);
        return *this;
    }
}

Reason for adding const to the parameter:
1. Prevent parameters from being changed.
2. After adding const, the parameter can accept both const type parameters and non const type parameters.

Reason for adding reference to parameters: reduce the copy when referring to parameters once, and improve program efficiency.

For overloaded functions of assignment class, the general return type is the reference type. Here, the overloaded return type of = is BigInteger &, which is a reference to BigInteger type variables.

Reason for using reference type return value:
1. Ibid., reduce one copy and improve program efficiency;
2. When using continuous assignment ( a = b ) = c (a=b)=c (a=b)=c, if the return value of the overloaded function type is not a reference type, it will be returned after execution a = b a=b After a=b, a temporary object (which can be considered as temp) will be returned, and then the temp=c operation will be executed. Therefore, the assignment of a in the second step has not been changed.

struct student{
    int val;
    student(int x){
        val=x;
    } 
    student operator = (const student&y){
        val=y.val;
        return *this;
    }
};
int main(){
    student a(1),b(2),c(3);
    (a=b)=c;
    printf("%d\n",a.val);//The output is 2
}

Generally, if the return value type of the function is reference, the return value is the reference of the current object.

Posted by Ulujain on Sun, 31 Oct 2021 12:34:04 -0700