运算符重载
我们都知道 1 + 1 = 2
这里面 + 运算符是设定好的相加
那如果我想用一个对象 + 另一个对象 得出一个我想要的特定的算法得出的值,那么就需要运算符重载
比如现在我想达到这样一个目的
A + B 返回的结果是他们的平方相加
那么我定义一个类
class Test { private: /* data */ public: Test(int a); ~Test(); int a; }; Test::Test(int a) { this->a = a ; } Test::~Test() { }
如果我直接在主函数中这样写
int main(int argc, char const *argv[]) { Test A(5),B(6); cout<<A + B<<endl; return 0; }
那肯定会报错的,因为 + 左右两边都不是基础类型
这个时候我们将 + 重载
使用这样的格式:
int operator+(const Test &A,const Test &B) { int c = A.a * A.a + B.a *B.a; return c; }
这样再在主函数中使用 A + B 就不会报错了,并且返回值为两个数的平方再相加。
上面的方法是使用全局函数重载+,下面我们试一下在类里面用成员函数重载运算符-
要注意的一点,当作为成员函数重载时,this作为左操作数
也就是说如果我要在成员函数里面这样写
int operator -(const Test &A,const Test &B);
就会报错
正确的写法是:
int operator -(const Test &A);
然后重载 再调用
int Test::operator -(const Test &A) { int c = this->a * this->a - A.a *A.a; return c; } int main(int argc, char const *argv[]) { Test A(5),B(6); cout<<A + B<<endl; cout<<A - B<<endl; return 0; }
输出结果:
61 -11
当然返回值可以是类
Test operator*(const Test &A,const Test &B) { Test test(0); test.a = A.a * B.a; return test; } int main(int argc, char const *argv[]) { Test A(5),B(6); cout<<A + B<<endl; cout<<A - B<<endl; Test C = A * B; cout<<C.a<<endl; return 0; }
也可以重载为友元函数 加一个关键字friend 可以访问私有属性
在多数情况下,将运算符重载为类的成员函数和类的友元函数都是可以的。但成员函数运算符与友元函数运算符也具有各自的一些特点:
(1) 一般情况下,单目运算符最好重载为类的成员函数;双目运算符则最好重载为类的友元函数。
(2) 以下一些双目运算符不能重载为类的友元函数:=、()、[]、->。
(3) 类型转换函数只能定义为一个类的成员函数而不能定义为类的友元函数。
(4) 若一个运算符的操作需要修改对象的状态,选择重载为成员函数较好。
(5) 若运算符所需的操作数(尤其是第一个操作数)希望有隐式类型转换,则只能选用友元函数。
(6) 当运算符函数是一个成员函数时,最左边的操作数(或者只有最左边的操作数)必须是运算符类的一个类对象(或者是对该类对象的引用)。如果左边的操作数必须是一个不同类的对象,或者是一个内部类型的对象,该运算符函数必须作为一个友元函数来实现。
(7) 当需要重载运算符具有可交换性时,选择重载为友元函数。
上面提到的都是双目运算符
下面我们看一下如果想重载 ++ 应该怎么做
++ 有两种 一种是 i++ 一种是++i
首先声明成员函数在类里面
class Test { private: /* data */ public: Test(int a); ~Test(); int operator -(const Test &A); int operator++(); int operator++(int); int a; };
第二个声明加了一个int,就是为了区分i++ 和++i ,有int是i++
然后实现他们
int Test::operator++() { return this->a+1; } int Test::operator++(int) { return this->a-1; }
在主函数中调用
int main(int argc, char const *argv[]) { Test A(5),B(6); int ads = ++A; cout<<ads<<endl; int sus = A++; cout<<sus<<endl; return 0; }
输出结果
6 4
还是++ ,我们看一下友元函数的方式:
先声明
class Test { private: /* data */ public: Test(int a); ~Test(); int operator -(const Test &A); friend int operator++(const Test &A); friend int operator++(const Test &A,int); int a; };
然后定义
int operator++(const Test &A) { return A.a+1; } int operator++(const Test &A,int) { return A.a-1; }
输出和刚才的相同
重载下标[]
class Test { private: /* data */ public: int operator[](int i); Test(); int a[10]; }; Test::Test() { for (auto i = 0; i != 10; i++) { a[i] = i+1; } } int Test::operator[](int i) { if (i>=10 || i<0) { cout<<"不符合规范"<<endl; return 0; } while (i<10) { return a[i]; } } int main(int argc, char const *argv[]) { Test A; cout<<A[1]<<endl; cout<<A[12]<<endl; return 0; }
输出结果
2 不符合规范 0
重载运算符()、[]、->、或者赋值运算符=时,只能将它们重载为成员函数,不能重载为全局函数。