#C++ Day27 November 11 2025

//Object – Oriented 7 – 1 Operator Overloading

//运算符重载

#include <iostream>

#include <string>

using namespace std;

/*

运算符重载就是对一个已有的运算符进行一个重新定义

对不同的数据结构有不同处理

*/

/*

+

4+5=9

class A{

};

A a;

A b;

a + b;

*/

int main() {

//1.加法运算符

int a = 520;

int b = 1314;

cout << a + b << endl; 

//2.字符串拼接

string c = “520”;

string d = “1314”;

cout << c + d << endl; //实际上就是运算符重载的技术

string e = “我”;

string f = “爱你”;

cout << e + f << endl;

return 0;

}

//Object – Oriented 7 – 2 Plus Operator Overloading

//加号重载

#include <iostream>

using namespace std;

/*

+号

*/

//复数类 实部和虚部 组成  实部和实部相加 虚部跟虚部相加

class Complex {

friend Complex operator+(Complex& a, Complex& b);

//因为real和image是别的函数里面的私有成员,我想用全局函数去访问私有成员的话用友元就可以了

friend Complex operator-(Complex& a, Complex& b);

public:

Complex() :real(0), image(0) {//初始化列表

}

Complex(int real, int image) {

this->real = real;//用this指针避免变量名重复的冲突问题

this->image = image;

}

/*

Complex add(Complex& other) {//传进来的Complex我们叫它other

Complex ret;//结不变

ret.real = this->real + other.real; //自己的实数部分等于实数加实数 this 是指针 需用箭头来获取变量,other是引用 是一个对象 所以用.来获取变量

ret.image = this->image + other.image;

return ret;

}

*/

/*

//这里采用成员函数的形式进行加法运算符重载

Complex operator+(Complex& other) {//传进来的Complex我们叫它other

Complex ret;//结不变

ret.real = this->real + other.real; //自己的实数部分等于实数加实数 this 是指针 需用箭头来获取变量,other是引用 是一个对象 所以用.来获取变量

ret.image = this->image + other.image;

return ret;

}

*/

//a+bi

void Print() {

cout << real << ‘+’ << image << ‘i’ << endl;

}

private:

int real;//实部

int image;//虚部

};

//变成全局函数后 变成两个对象相加

Complex operator+(Complex& a,Complex& b) {

Complex ret;//结不变

ret.real = a.real + b.real; //自己的实数部分等于实数加实数 this 是指针 需用箭头来获取变量,other是引用 是一个对象 所以用.来获取变量

ret.image = a.image + b.image;

//因为real和image是别的函数里面的私有成员,我想用全局函数去访问私有成员的话用友元就可以了

return ret;

}

Complex operator-(Complex& a, Complex& b) {

Complex ret;//结不变

ret.real = a.real – b.real; //自己的实数部分等于实数加实数 this 是指针 需用箭头来获取

变量,other是引用 是一个对象 所以用.来获取变量

ret.image = a.image – b.image;

//因为real和image是别的函数里面的私有成员,我想用全局函数去访问私有成员的话用友元就可以了

return ret;

}

int main() {

Complex a(10,20);

Complex b(5, 8); //a和b两个实例化对象

//Complex c = a.add(b);//实例化一个c,a调用add接口后把b传进去的结果

//Complex c = a.operator+(b);

Complex c = a+b; //加法运算符重载 

c.Print();

Complex d = a – b;//复数的加减可以用 重载 乘除规格会变掉 所以不行

d.Print();

//需要把调用的函数变成一个加号最理想

return 0;

}

//Object – Oriented 7 – 3 Left Shift Overloading

//左移重载

#include <iostream>

using namespace std;

/*

Complex c;

<< 左移 目的 就是为了把这个对象输出出来 我要进行输出的话一定会调用cout.operator << (c),operator<<是cout的一个成员函数

cout.operator << (c)

//但是我们现在希望它必须是Complex的成员函数

Complex的成员函数的话c必须得放在左边

如果这样就会变成 c<<cout 这个达不到想要的效果

//成员函数的重载  需要用全局函数的

c.operator <<(cout)

我们希望cout << c

所以我们需要它从成员函数里面抽出来 变成一个全局函数

所以需要用 全局函数作为友元声明

*/

class Complex {

friend Complex operator+(Complex& a, Complex& b);

//因为real和image是别的函数里面的私有成员,我想用全局函数去访问私有成员的话用友元就可以了

friend Complex operator-(Complex& a, Complex& b);

//friend void operator<<(ostream& cout, Complex a);

friend ostream& operator<<(ostream& cout, Complex a);//友元的函数声明也要改过来

public:

Complex() :real(0), image(0) {//初始化列表

}

Complex(int real, int image) {

this->real = real;//用this指针避免变量名重复的冲突问题

this->image = image;

}

/*

Complex add(Complex& other) {//传进来的Complex我们叫它other

Complex ret;//结不变

ret.real = this->real + other.real; //自己的实数部分等于实数加实数 this 是指针 需用箭头来获取变量,other是引用 是一个对象 所以用.来获取变量

ret.image = this->image + other.image;

return ret;

}

*/

/*

//这里采用成员函数的形式进行加法运算符重载

Complex operator+(Complex& other) {//传进来的Complex我们叫它other

Complex ret;//结不变

ret.real = this->real + other.real; //自己的实数部分等于实数加实数 this 是指针 需用箭头来获取变量,other是引用 是一个对象 所以用.来获取变量

ret.image = this->image + other.image;

return ret;

}

*/

//a+bi

void Print() {

cout << real << ‘+’ << image << ‘i’ << endl;//cout的对象是ostream

}

void Printsub() {//减法需要配套的subprint函数

//减法感觉需要配套的print函数,否则减法后虚部为负数会有类似5 + -8i的情况

if (image > 0) {

cout << real << ‘+’ << image << ‘i’ << endl;//复数是正数的情况

}

else if (image == 0) {//复数为0的情况

cout << real << endl;

}

else {//复数为负数的情况

cout << real << image << ‘i’ << endl;

}

}

private:

int real;//实部

int image;//虚部

};

//变成全局函数后 变成两个对象相加

Complex operator+(Complex& a, Complex& b) {

Complex ret;//结不变

ret.real = a.real + b.real; //自己的实数部分等于实数加实数 this 是指针 需用箭头来获取变量,other是引用 是一个对象 所以用.来获取变量

ret.image = a.image + b.image;

//因为real和image是别的函数里面的私有成员,我想用全局函数去访问私有成员的话用友元就可以了

return ret;

}

Complex operator-(Complex& a, Complex& b) {

Complex ret;//结不变

ret.real = a.real – b.real; //自己的实数部分等于实数加实数 this 是指针 需用箭头来获取变量,other是引用 是一个对象 所以用.来获取变量

ret.image = a.image – b.image;

//因为real和image是别的函数里面的私有成员,我想用全局函数去访问私有成员的话用友元就可以了

return ret;

}

/*

void operator<<(ostream& cout, Complex a) {//std不用写直接写ostream& cout ,然后把Complex对象传进来

cout << a.real << ‘+’ << a.image << ‘i’;//私有成员无法直接访问,需要变成一个友元

}

*/

//类型改成ostream& 来返回

ostream& operator<<(ostream& cout, Complex a) {//std不用写直接写ostream& cout ,然后把Complex对象传进来

cout << a.real << ‘+’ << a.image << ‘i’;//私有成员无法直接访问,需要变成一个友元

return cout;

}

int main() {

Complex a(10, 20);

Complex b(5, 8); //a和b两个实例化对象

//Complex c = a.add(b);//实例化一个c,a调用add接口后把b传进去的结果

//Complex c = a.operator+(b);

Complex c = a + b; //加法运算符重载 

//c.Print();

Complex d = a – b;//复数的加减可以用重载,复数乘除规则会变掉 所以不行

//d.Printsub();

//需要把调用的函数变成一个加号最理想

//这里的左移c实际上调用了 operator<<(cout,c) 如果我再调左移的话会利用返回值来进行左移的 但是上面的返回值目前是void空类型

cout << c << endl<<endl; //如果我们希望左移 列式 输出  也就是说能不断地往后面加上左移符号   所以函数再调用完毕后同样需要返回同一个值ostream

return 0;

}

//Object – Oriented 7 – 4 Increment Overloading

//递增运算符重载

#include <iostream>

using namespace std;

/*

递增运算符 ++ 的重载

前置++

后置++

复数的++

其实就是把实部和虚部++

*/

class Complex {

friend ostream& operator<<(ostream& c, Complex a);

public:

Complex() :real(0), image(0) {}

Complex(int real, int image) {

this->real = real;

this->image = image;

}

/*

void operator++() {//++后面只有一个操作符 不需要其它东西

//要输出得把类型改成Complex

this->real += 1;

}

*/

/*

Complex operator++() {//++后面只有一个操作符 不需要其它东西

//要输出得把类型改成Complex

this->real += 1;

return *this;//this指向自己 进行一次解引用就相当于返回了自己

}

*/

Complex& operator++() {//++后面只有一个操作符 不需要其它东西 加上引用确保还是原来的对象

//要输出得把类型改成Complex

this->real += 1;

return *this;//this指向自己 进行一次解引用就相当于返回了自己

}//前置++ 实现了 

//前置++返回原对象

Complex operator++(int) {//这里不能加引用 因为这是一个临时对象 这是一个拷贝

//有参数就是后置++

//需要先存一个对象

Complex c = *this;

this->real += 1;

return c;

}//后置++ 实现了

//后置++返回新的拷贝对象

private:

int real;

int image;

};

ostream& operator<<(ostream& c, Complex a) {

c << a.real << ‘+’ << a.image << ‘i’;

//cout其实就是我们传进来的c

return c;

}

int main() {

int x = 1;

cout << ++(++x) << endl;

cout << x << endl;//前两个输出的值是一样的

Complex a(10, 10);

cout << a << endl;

//++a;//这里先实现前置++

cout << ++(++a) << endl;//如果前面不加引用 ++a会生成新对象 跟原来的a对象不一样 没有关系了

cout << a << endl;

cout << a++ << endl;//跟a一样的( 输出的倒数第二第三行 一样)

cout << a << endl;//这一行要多1

//cout << ((a++)++)++  << endl;

//cout << a << endl;//要差3

//int b = 5;

////左值就是赋值语句左边出现的表达式 表示为一个有内存的对象 它可以被修改的

//cout << ((b++)++)++ << endl; //++作为后置++的时候 就不能再调用++了

////但这个b++不能被修改 后置的递增运算符返回值不需要是原来的对象

//cout << b << endl;

/*

x = 5;

x++;//这个对象还是5

*/

return 0;

}