目录
引入:为什么要进行运算符重载?
C++编译器能够实现预定义的基本数据类型之间的运算,但不能对自定义的数据类型之间的运算。运算符重载的目的是将系统已经定义的运算符用于新定义的数据类型,从而使得同一个运算符作用于不同类型的数据导致不同类型的行为。
一.运算符重载的定义
1.定义格式
函数类型 operator 运算符名(形参列表)
{ 对运算符的重载处理 }
如:operator+就是对运算符“+”进行重载
二.运算符的规则
1.重载运算符必须和用户定义的自定义类型对象一起使用,其参数至少应有一个是类对象或者类对象的引用。
2.重载运算符的函数不能有默认的参数。
3.运算符之间的优先级不变
4.C++不允许用户自己定义新的运算符
4.不能重载的运算符如下:.,.*,::,sizeof,?:。
三.运算符重载的两种方式
1.运算符重载作为类内的成员函数
格式:
class 类名
{ ...
返回类型 operator 运算符(形参表);
...
};
在类外定义运算符重载函数格式:
返回类型 类名::operator运算符 (形参表)
{
函数体
}
2.运算符重载作为类内的友元函数
格式:
class 类名
{ ...
friend 返回类型 operator 运算符(形参表);
...
};
在类外定义运算符重载函数格式:
返回类型 operator运算符 (形参表)
{
函数体
}
四.常见的运算符重载
1.单目运算符++和--的重载
注意:这里运算符++作为类内的成员函数,运算符--作为类的友元函数
{
//前后自增为成员函数
Point& operator++()//前置
{
if (x < 4096) ++x;
if (y <2160)++y;
return *this;
}
Point operator++(int)//后置
{
Point temp(*this);
if (x < 4096) ++x;
if (y < 2160)++y;
return temp;
}
friend Point& operator--(Point& a);//前置自减
friend Point operator--(Point& a,int);//后置自减
};
//类外
Point& operator--(Point& a)
{
if (a.x > 0) --a.x;
if (a.y > 0) --a.y;
return a;
}
Point operator--(Point& a, int)
{
Point temp(a);
if (a.x > 0) --a.x;
if (a.y > 0) --a.y;
return temp;
}
//int不起实际作用,只作为前置后置的区分
2.赋值运算符=的重载
//类内
myString& operator=(const myString& b) {
if (this != &b && b.data != nullptr)
{
delete[] data;
data = nullptr;
len = b.len;
data = new char[len + 1];
strcpy(data, b.data);
}
else if (b.data == nullptr)
return *this;
}
3.双目运算符+和-的重载
//类内
myString operator+(const myString& b)
{
//要开辟一个新的对象,更大的数组
myString m;
m.len = len + b.len;//所有的字符个数
m.data = new char[m.len + 1];
strcpy(m.data, data);//字符串拷贝
strcat(m.data, b.data);//字符串连接
return m;
}
//-也是类似
4.流插入运算符<<和流提取运算符>>的重载
理解:ostream对象对<<运算符进行了重载,将其转换为一个输出工具,cout是ostream类的一个对象,它是智能的,能够识别所有的C++基本类型。要使cout能够识别用户自定义的对象,就要在用户自定义类中对<<运算符进行重载,让用户自定义类知道如何使用cout。
{---
friend ostream& operator<<(ostream& os, myString& s);
friend istream& operator>>(istream& os, myString& s);
---
};
//类外
//重载<<
ostream& operator<<(ostream& os, myString& S)
{
if (S.size() != 0)
{
os << S.size() << " " << ":" << " ";
os << S.data;
}
else
{
os << "0";
}
return os;
}
istream& operator>>(istream& is, myString& S)
{
string tmp2;
getline(cin, tmp2);
/*string tmp;
is >> tmp;*/
S.set(tmp2.c_str());
return is;
}
//作为类的友元函数,就能够访问类内的所有成员
5.下标运算符[]的重载
理解:
这两个函数是重载了下标运算符[]的成员函数,用于实现对类对象的下标访问操作。第一个函数是用于写入操作的重载版本,而第二个函数是用于只读操作的重载版本。
1.char& operator[](int i): 这个函数用于写入操作,它返回一个字符的引用。在函数内部,它首先检查传入的索引值是否在有效范围内(0到len之间,len可能是类中的某个成员变量),如果是,则返回对应位置的数据成员 data[i] 的引用,允许在外部通过对象的下标访问来进行写入操作。但是,如果索引值超出了有效范围,则该函数没有返回值,这可能导致编译器发出警告或错误,因为函数声明的返回类型是 char&,即返回一个字符的引用,但在超出范围时却没有返回任何值。
2.const char& operator[](int i) const: 这个函数用于只读操作,它返回一个常量字符的引用。与第一个函数不同的是,这个函数被声明为常量成员函数(通过 const 关键字),表示它不会修改对象的状态。它返回的是数据成员 data[i] 的常量引用,因此外部只能通过对象的下标访问来进行读取操作,而不能进行写入操作。
//类内
char& operator[](int i)//用于写入,作为左值
{
if (i >= 0 && i < len)
return data[i];
}
//无法修改对象的状态
const char& operator[](int i) const {。作为右值
return data[i];//只读
}
作者主要是对运算符重载书写格式不太熟悉,本文章提供后续查看。