1、C++的运算符重载
使对象的运算表现得和编译器内置类型一样
template<typename T>
T sum(T a, T b)
{
return a+b;//a.operator+(b)
}
- 如果T是编译器的内置类型的话,编译器对a+b是可以做的。
- 但是如果T是我们自定义的对象类型,a和b是两个对象,对象和对象之间该怎么相加???编译器是不知道的。
- 这里就要使用运算符的重载了。
return a+b;//a.operator+(b),a调用自己的加法函数,将b当成传进去
加法运算符的重载函数。
2、复数类的实现(运算符重载)

2.1、构造函数
在这里,编译器能不能将一个整数变为一个对象?
- 这里涉及 实参类型 到 形参类型 的类型强制转换!
- 看编译器有没有提供带整数形参的构造函数 CComplex(int)的构造函数!

是可以的,因为我们写的构造函数可以是三种类型的构造函数:

2.2、 “+” 重载函数



我们要定义一个全局的加法函数,并且在类中定义为类的友元函数:


并且,现在可以将类内的 “+” 重载函数 成员方法屏蔽了,全局的 “+” 重载函数更好!
全局的 “+” 重载函数 可以实现 对象 “+” 对象、整数 “+” 对象、对象 “+” 整数
2.3、++和–前置后置运算符重载函数
operator++()表示前置++ operator++(int)表示后置++ 这个int只是为了区分,没有任何作用


2.4、“+=”运算符重载函数


2.5、“<<” 和 “<<”运算符重载
- 这个输出<<运算符重载,对象不在左边,所以不可以提供成员方法 (需要对象在左边进行调用),所以定义成全局方法



#include <iostream>
using namespace std;
class CComplex
{
public:
//CComplex() CComplex(20) CComplex(30, 30)
CComplex(int r = 0, int i = 0)
:mreal(r), mimage(i) {}
//指导编译器怎么做CComplex类对象的加法操作
CComplex operator+(const CComplex &src)
{
//写法1:
CComplex comp;//局部对象
comp.mreal = this->mreal + src.mreal;
comp.mimage = this->mimage + src.mimage;
return comp;
//写法2:
return CComplex(this->mreal + src.mreal,
this->mimage + src.mimage);//对象的优化
}
//后置++
CComplex operator++(int)
{
//方法1:
//CComplex comp = *this;
//mreal += 1;
//mimage += 1;
//return comp;
//方法2:
return CComplex(mreal++, mimage++); //返回的是局部对象,返回值用CComplex接收
}
//前置++
CComplex& operator++()
{
mreal += 1;
mimage += 1;
return *this; //出函数,*this是存在的,不是局部对象,返回值用CComplex&
}
void operator+=(const CComplex& src)
{
mreal += src.mreal;
mimage += src.mimage;
}
void show() { cout << "real:" << mreal << " image:" << mimage << endl; }
private:
int mreal;//实部
int mimage;//虚部
//这个全局的方法成了这个类的朋友,这个全局方法可以访问这个类的实部和虚部
friend CComplex operator+(const CComplex& lhs, const CComplex& rhs);
friend ostream& operator<<(ostream& out, const CComplex& src);
friend istream& operator>>(istream& in, CComplex& src);
};
CComplex operator+(const CComplex& lhs, const CComplex& rhs)//加法的全局运算符重载
{
return CComplex(lhs.mreal + rhs.mreal, lhs.mimage + rhs.mimage);
}
ostream& operator<<(ostream& out, const CComplex& src)//输出是从左向右运算的
{
out << "mreal:" << src.mreal << " mimage:" << src.mimage << endl;
return out;
}
istream& operator>>(istream& in, CComplex& src)
{
in >> src.mreal >> src.mimage;
return in;
}
int main()
{
CComplex comp1(10, 10);
CComplex comp2(20, 20);
//comp1.operator+(comp2) 加法运算符的重载函数
CComplex comp3 = comp1 + comp2;//左边是对象,优先调用成员方法 ,成员方法没有的话就去找全局方法
comp3.show();
CComplex comp4 = comp1 + 20;//左边是对象,优先调用成员方法,成员方法没有的话就去找全局方法
//comp1.operator+(20) int->CComplex 编译器会找有没有CComplex(int)生成1个临时对象 ,然后进行相加
comp4.show();
//编译器做对象运算的时候,会调用对象的运算符重载函数(优先调用成员方法);如果没有成员方法
//就在全局作用域找合适的运算符重载函数
// 我们在全局提供 ::operator+(30, comp1) 30和comp1都当做实参传进去
CComplex comp5 = 30 + comp1;//30在里面必须要有趋势要做类型的转换!!! 无法调用成员方法的加法运算符重载函数
//看复数类型有没有带整型参数的构造函数来生成1个临时对象让lhs引用,就生成一个实部是30,虚部是0的临时对象
comp5.show();
//CComplex operator++(int)
comp5 = comp1++;
// ++ --是单目运算符 operator++()表示前置++ operator++(int)表示后置++ 这个int只是为了区分,没有任何作用
comp1.show();
comp5.show();
//CComplex operator++()
comp5 = ++comp1;
comp1.show();
comp5.show();
//void comp1.operator+=(comp2) ::operator+=(comp1, comp2)
comp1 += comp2;
//comp1.show();//对象信息的输出
//这个输出<<运算符重载,对象不在左边,所以不可以提供成员方法 ,所以定义成全局方法
//cout ::operator<<(cout, comp1) 流对象是不断放,取东西,是变化的,不能加const
//void << endl; 因为要连续输出,不能用void作为返回值
//连续的输出,应该把cout返回:ostream& operator<<(ostream &out, const CComplex &src)
//ostream &out,流对象是不断变化的,前面不能加const
cout << comp1 << endl;
cin >> comp1 >> comp2;
cout << comp1 << comp2 << endl;
return 0;
}
本文介绍了C++中的运算符重载技术,如何使自定义对象支持像内置类型一样的运算操作。通过一个复数类的实现,详细展示了构造函数、加法运算符重载、前置后置递增运算符重载以及“+=”、“<<”和“>>”运算符的重载方法。此外,还展示了如何通过全局函数作为友元来实现这些重载,确保对象间、整数与对象间的各种运算组合都能正确工作。
&spm=1001.2101.3001.5002&articleId=124721788&d=1&t=3&u=7a02a0f53b634d9bab4c7b839b1f8338)
1991

被折叠的 条评论
为什么被折叠?



