11.1基本的双目运算符:
返回值类型 operator<运算符号>(参数列表)
{
函数体;
}
如果重载为全局的友元函数,则双目运算符有两个参数,编译器根据函数名和参数列表匹配相对应的函数
eg: //运算符重载函数,从新定义了“+”的作用,使得“+”能够处理Complex和Complex的操作数
Complex operator+(Complex c1,Complex c2)
{
cout << "operator+(Complex c1,Complex c2)" <<endl;
double r = c1.real_ + c2.real_;
double i = c1.img_ + c2.img_;
return Complex{r,i};//临时对象
}
如果重载为类的成员函数,则双目运算符只有一个参数,还有一个参数呢?
因为成员函数中,默认有一个this指针,且编译器默认使用运算符左侧的对象调用该运算符函数,把运算符右侧的参数作为函数的参数
eg: //运算符重载函数,从新定义了“+”的作用,使得“+”能够处理Complex和Complex的操作数
Complex operator+(Complex &c1)
{
cout << "成员函数::operator+(Complex &c1)" <<endl;
double r = this->real_ + c1.real_;
double i = this->img_ + c1.img_;
return Complex{r,i};//临时对象
}
注意:
1.即重载为类的全局函数又重载为友元函数,会调用哪一个?
会报错,二义性错误!!!!
const对象只能调用const函数,但是非const对象既可以调用非const又能调用const函数
11.2输入输出运算符:>>/<<
11.2输入输出运算符:>>/<<
返回值类型 operator<运算符号>(参数列表)
{
函数体;
}
注意:输入输出运算符只能重载为全局的友元函数
ostream& operator<<(ostream &out,Rect &r)
{
out << r.c << "+" << r.w << endl;
return out;
}istream& operator>>(istream &in,Rect &r)
{
in >> r.c >> r.w;
return in;
}
11.3下标运算符[ ]:
11.3下标运算符[]:必须以成员函数的形式进行重载,下标运算只和当前类有关系
该函数在类中的重载形式如下:
返回值类型 &operator[](参数); or const 返回值类型 &operator[](参数) const;
第一种方式,[]不仅可以访问元素,还可以修改对象中的元素
第二种方式,[]只能访问而不能修改
在实际开发中,我们应该同时提供上面两种重载方式,是为了适应const对象
const对象只能调用const函数,如果不提供第二种方式,const对象就不能通过[]访问成员
11.4单目运算符++/--
单目运算符分为前置和后置,在运算符重载的时候,为了区分前置和后置
使用一个int的占位参数,无其他含义
后置++操作符需要一个额外的int类型的占位参数
前置++操作符不需要额外的操作
11.5总结
1.运算符重载的本质就是函数重载,目的是让自己定义的类类型也能够使用运算符
2.只能重载已有的运算符,不能创造新的运算符
3.可以重载大多数运算符,但是以下运算符不能重载
3.1.取成员运算符 "."
3.2.成员对象指针 ".*,->*"
3.3.作用域运算符 "::"
3.4.条件运算符 "?:"
3.5.sizeof
4.运算符函数由编译器自动调用,但是也可以像普通函数一样直接调用它
5.重载为成员函数还是全局函数
= () [] -> 必须重载为成员函数
<< >> 必须重载为全局友元函数
6.只有当操作数中至少有一个是自定义类型的对象时,才需要函数重载
友元函数:
返回值类型 operator++(类型 &) //前置++
返回值类型 operator++(类型 &,int) //后置++,int仅仅表示这个是后置++操作
成员函数:
返回值类型 operator++() //前置++
返回值类型 operator++(int) //后置++,int仅仅表示这个是后置++操作
问题:1.为什么需要返回值,而且是返回引用?
目的是为了使得cout << "hello" << 50这种可以连续输出
2.为什么返回引用?
引用目的是避免调用拷贝构造函数产生临时对象!
3.C++规定,赋值运算符重载函数,只能重载为类的非静态成员函数,不能是静态函数,也不能是友元函数
3.1 为什么不能是静态成员函数?
因为静态函数只能访问静态成员,不能操作非静态成员函数
因为静态成员函数没有this指针
说明:
一个类在默认情况下会生成一些函数,如:构造函数,拷贝构造函数,析构函数等
如果不需要编译器默认生成某些函数,只需要在该函数的后面加上一个=delete即可
如:
ostream类不需要拷贝构造函数
basic_ostream(const basic_ostream&) = delete;
如果需要编译器自动生成某些函数.只需要在该函数的后面加上一个=default即可
如:
时间类只有一个带参数的构造函数,还需要它生成一个默认的无参构造函数
Date()=default; //编译器默认生成一个无参构造函数,函数体为空