1 运算符重载
1.1 运算符重载基本概念
运算符重载(operator overloading)只是一种”语法上的方便”,也就是它只是另一种函数调用的方式。
在c++中,可以定义一个处理类的新运算符。这种定义很像一个普通的函数定义,只是函数的名字由关键字operator及其紧跟的运算符组成。差别仅此而已。它像任何其他函数一样也是一个函数,当编译器遇到适当的模式时,就会调用这个函数。
语法:
定义重载的运算符就像定义函数,只是该函数的名字是operator@,这里的@代表了被重载的运算符。函数的参数中参数个数取决于两个因素
- 运算符是一元(一个参数)的还是二元(两个参数);
- 运算符被定义为全局函数(对于一元是一个参数,对于二元是两个参数)还是成员函数 (对于一元没有参数,对于二元是一个参数-此时该类的对象用作左耳参数)
注意:
1.定义重载运算符时根据需要定义返回值,本示例中返回为一个新对象因此返回test类型。
2. 重载的运算符的一元还是二元可以通过全局函数的重载参数得出
示例:
class test
{
public:
test(){
}
test(int m_a,int m_b):a(m_a),b(m_b)
{
}
//成员函数重载运算符 二元函数
test operator+(test & p)//转化为p1+p2
{
test t1;
t1.a = this->a + p.a;
t1.b = this->b + p.b;
return t1;
}
int a;
int b;
};
//全局函数重载运算符 二元参数
//test operator+(test &p1,test& p2)//p1+p2
//{
// test tmp;
// tmp.a = p1.a+p2.a;
// tmp.b = p1.a + p2.a;
// return tmp;
//}
void usi()
{
test p1(10,20);
test p2(20,30);
//使用符号重载 全局和成员函数重载只需要写一个,写俩个有二义性
test p3= p1 + p2;//30 50 p1.operator+(p2) 全局函数 operator+(p1,p2)
cout<<"p3.a"<<p3.a<<" "<<"p3.b"<<p3.b<<endl;
}
void main()
{
usi();
}
[两个极端]
有些人很容易滥用运算符重载。它确实是一个有趣的工具。但是应该注意,它仅仅是一种语法上的方便而已,是另外一种函数调用的方式。从这个角度来看,只有在能使涉及类的代码更易写,尤其是更易读时(请记住,读代码的机会比我们写代码多多了)才有理由重载运算符。如果不是这样,就改用其他更易用,更易读的方式。
对于运算符重载,另外一个常见的反应是恐慌:突然之间,C运算符的含义变得不同寻常了,一切都变了,所有C代码的功能都要改变!并非如此,对于内置的数据类型的表示总的所有运算符是不可能改变的。
1.2 运算符重载碰上友元函数
友元函数是一个全局函数,和我们上例写的全局函数类似,只是友元函数可以访问某个类私有数据。
案例: 重载左移操作符(<<),使得cout可以输出对象。
//cout<<p1.a<<endl;没有问题,但是cout<<p1 就会报错,无法输出p1,类型不匹配,所以进行重载,
//但是重载左移运算符不可以变为成员函数,变为成员函数调用<< 会变为p1<<跟需求cout<<冲突
#include<iostream>
#include<string>
using namespace std;
class person
{
friend ostream& operator<<(ostream&os,person &p1);//友元函数可以访问私有成员
public:
person(){
};
person(int a,int b):age(a),num(b)
{
}
void test()
{
cout<<age<<endl;
}
private:
int age;
int num;
};
ostream& operator<<(ostream&cout,person &p1)//cout << p1 先左后右,左 为cout 右 为 p1
{
cout<<p1.age<<" "<<p1.num;
return cout;//返回ostream 让这个<<继续输出,