浅谈结构体内重载运算符

本文探讨了如何在结构体中通过重载运算符如+实现高精度加法,强调了重载运算符在提高代码简洁性和效率方面的优势。讲解了重载运算符的原则,尤其是参数处理和返回值类型选择,以及在BigInteger和student结构体中的应用实例。

浅谈结构体内重载运算符

1.重载运算符的作用

对结构体类型的变量使用重载后的运算符代替成员函数完成一系列任务。当然,我们可以使用成员函数直接完成这些任务,但使用起来没有重载运算符后美观直接。
举个直观的例子:在实现高精度加减法时,如果你能直接用c=a+bc=a+bc=a+b表示高精度加法,是不是比c=add(a,b)c=add(a,b)c=add(a,b)要直观的多?

2.重载运算符的原则

当重载运算符函数定义在类的内部时,此时operator的参数数目比具体重载的操作符所需的操作数数目少一,因为此时使用了一个隐藏参数*this,并将其作为左操作数(第一个操作数)。
当重载运算符函数定义在类的外部,则参数数目与具体重载的操作符所需的操作数数目相同。

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;
	}
}

上面的代码中,重载函数定义在类的内部,故在函数里只需传入一个参数,函数中的s[i]s[i]s[i]代表的是当前对象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;
}

这是定义在类外部的代码。

3.重载运算符最需要考虑的即为参数与返回值问题

以定义在类内部的代码为例进行讲解

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;
    }
}

参数加const的原因:
1.防止参数被改变。
2.加上const之后,参数既可以接受const类型的参数,也可以接受非const类型的参数。

参数加引用的原因:减少一次引用参数时的拷贝,提高程序效率。

对于赋值类重载函数,一般返回类型为引用类型,此处对=的重载返回类型为BigInteger&,即是对BigInteger类型变量的一个引用。

使用引用类型返回值的原因:
1.同上,减少一次拷贝,提高程序效率;
2.在使用连续赋值(a=b)=c(a=b)=c(a=b)=c时,若重载函数类型返回值不是引用类型,则在执行完a=ba=ba=b后会返回一个临时对象(可认为是temp),然后执行temp=c操作,故a在第二步赋值并未被改变。

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);//输出为2
}

一般地,如果函数返回值类型为引用,返回值就是当前对象的引用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值