浅谈结构体内重载运算符
1.重载运算符的作用
对结构体类型的变量使用重载后的运算符代替成员函数完成一系列任务。当然,我们可以使用成员函数直接完成这些任务,但使用起来没有重载运算符后美观直接。
举个直观的例子:在实现高精度加减法时,如果你能直接用
c
=
a
+
b
c=a+b
c=a+b表示高精度加法,是不是比
c
=
a
d
d
(
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
=
b
a=b
a=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
}
一般地,如果函数返回值类型为引用,返回值就是当前对象的引用。