Discussion on overload operator in structure

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.
For example, when implementing high-precision addition and subtraction, if you can directly use \ (c=a+b \) to represent high-precision addition, is it more intuitive than \ (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 only one parameter needs to be passed in the function. The \ (s[i] \) in the function represents the \ (s[i] \) of the current object.

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 \), if the return value of overloaded function type is not reference type, a temporary object (which can be considered as temp) will be returned after executing \ (a=b \), and then 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.

Added by cnagra on Sun, 31 Oct 2021 22:37:03 +0200