C++中预定义的运算符操作对象只能是基本数据类型,许多用户自定义类型比如类,也需要类似运算操作,所以我们需要对运算符进行重载,赋予它新的功能。
运算符重载函数成员函数运算符重载语法
数据类型 operator <运算符>(<形参列表>)
{
函数体
}
注:1.有些时候需要使用友元函数只需在前面加 friend
2.数据类型表示该函数返回值的数据类型
3.运算符表示需要重载的运算符(C++中除了以下运算符不能被重载,其他都可以)
点号 . 问号表达式 sizeof 作用域访问符::
4.运算符操作的对象是什么类型那么运算符重载函数就应该设计在哪个类。
下面我们通过一段代码来初步认识运算符的重载
#includeusing namespace std; class Demo{ public: //成员变量都可以通过构造函数参数初始化列表赋初值,CONST修饰的成员变量必须用初始化列表 Demo(int x):x(x){} //成员函数运算符重载,成员函数默认拥有指向对象的THIS指针,在函数形参列表中隐藏 //因此双目运算符的重载函数只能有一个形参,单目就没有形参 //成员函数运算符重载时,形参只能是1个或0个形参 int operator+(Demo &obj); int operator-(Demo &obj); private: int x; }; int Demo::operator+(Demo& obj) { return this->x+obj.x; } int Demo::operator-(Demo& obj)//Demo Demo::operator-(Demo& obj) { return this->x-obj.x;//Demo c(this->x-obj.x);return c } int main() { Demo a(1),b(3); //C++运算符默认的操作数类型是基本数据类型,无法计算两个类类型的对象运算所以必须重载 cout<
说明:
1.成员函数运算符重载,成员函数默认拥有指向对象的this指针(默认指向第一个操作对象),在函数形参列表中隐藏,所以双目运算符(操作数有几个就是几目)的重载函数只能有一个形参,单目则没有形参,总结一句话:成员函数运算符重载时,形参只能是1个或者0个。
2.如何判断该使用成员函数还是友元函数呢,由于友元函数打破了类的封装,所以他是不能使用this指针的,所以有些如果第一个操作数为基本类型或者标准类型(比如cout是ostream cin则是istream他们都是标准类型),就必须使用友元函数,下面我们会用几个例子来说明。
友元运算符重载函数语法:
friend 数据类型 operator(<形参列表>)
{
//函数体
}
注意:1.friend友元打破类的封装,因此运算符重载函数的形参个数=运算符操作个数
2. 当运算符的第一个操作数为基本类型或标准类型,就必须用友元,因为this指针不能指向他
看下面这段代码:
<<的重载
#includeusing namespace std; class Demo{ public: Demo(int x):x(x){} friend ostream& operator<<(ostream& out,Demo& obj)//标准输出流只能取别名不能定义参数去传> 递 { //将obj.x这个数值插入到标准数据流中 out< >>的重载
#includeusing namespace std; class Demo{ public: Demo(int x):x(x){} friend istream& operator>>(istream& input,Demo& obj) { input>>obj.x; return input; } int operator+(Demo& obj) { return this->x+obj.x; }//返回类型为INT所以不需要对<<进行重载 private: int x; }; int main(int argc,char* argv[]) { Demo a(15),b(1); cin>>a>>b;//标准输入流数据,先赋值给a,然后将标准输入流的数据,赋值给b,第一个操作数为CIN,不> 能用THIS指针指向,所以需要用友元 cout< 前++和后++的重载
#includeusing namespace std; class Demo{ public: Demo(int x):x(x){} #if 0 int operator++(){ // 前++ return ++this->x; } int operator++(int){ //后++,此处int没有任何作用,只是一个占位符,用来区分 前++ return this->x++; } #else // a++ ==> a = a + 1; friend int operator++(Demo &obj){ // 前++ return ++obj.x; } friend int operator++(Demo &obj, int){ //后++,此处int没有任何作用,只是一个占位符,用来区分 前++ return obj.x++; } private: int x; }; int main(int argc, char *argv[]) { Demo a(12); cout << ++a << endl; //cout << a.operator++() << endl; cout << a++ << endl; //cout << a.operator++(int) << endl; cout << a << endl; return 0; } 说明:我们在重载函数中加入一个int参数来区分前++和后++,因为a++等价于a=a+1;所以加了int的表示后++。
【】运算符的重载
注意【】运算符是双目运算符哦,并且重载时我们重载函数的返回值类型为引用类型,因为函数返回的是类的成员,要在函数外部进行修改,使用该成员的内容,那么数据类型必须为引用
#includeusing namespace std; class Demo{ public: Demo(int n) { p=new int[n];//在堆区开辟空间 } int &operator[](int i) { return p[i];//这里返回类型是引用类型,给所在空间取别名,方便进行修改 //如果函数返回的是类的成员,期待在函数外部能够修改使用该成员的内容,那么数据类型必须是引用 } private: int* p; }; int main() { Demo obj(6); for(int i=0;i<6;i++) { cin>>obj[i]; } for(int i=0;i<6;i++) { cout< ()运算符的重载
注意()运算符是多目运算符,根据他的的参数个数来决定
#includeusing namespace std; class Demo{ public: Demo(int x,int y) { this->m=x; this->n=y; } int operator()() { return (this->m+this->n); } int operator()(int x,int y) { return x+y; } private: int m; int n; }; int main() { Demo obj(12,34); cout << obj()<< endl; cout << obj(11,22)<< endl; return 0; }



