//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;
}