[下午6点左右,准备写今天的记录,但是有一个网友评论,于是我点击进去他的CSDN页面查看,网页跳出一个通知,询问我是否允许通知?好奇心驱使,我点击了允许,然后系统就瘫痪了。Win7, 360极速浏览器,不管鼠标点哪儿,键盘敲什么,都没反应,准确来说,只要我操作一下显示界面就闪一下,重启也没用。后来拔掉鼠标和键盘的USB,再重启,就正常了。计算机的东西真的好复杂啊,有时候硬件有毛病,有时候系统有毛病,有时候某一个软件有毛病,然后就莫名其妙地用不了电脑了。在未来的智能时代,如果人类不掌握一点点计算机知识,也许真的就成了现实中的楚门了]
[今天学的是运算符重载,听得云里雾里的,C++真的好难啊]
运算符重载
概念:对已知的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型
加号运算符重载
作用:实现两个自定义数据类型相加的运算
成员函数重载本质调用
Person p3 = p1.operator+(p2);
全局函数重载本质调用
Person p3 = operator+(p1,p2);
#include <iostream>
#include <string>
using namespace std;
// 加号运算符重载
class Person
{
public:
// 成员函数重载 + 号
// Person operator+(Person &p)
// {
// Person temp;
// temp.m_A = this->m_A + p.m_A;
// temp.m_B = this->m_B + p.m_B;
// return temp;
// }
int m_A;
int m_B;
};
// 全局函数重载+号
Person operator+(Person &p1,Person &p2)
{
Person temp;
temp.m_A = p1.m_A + p2.m_A;
temp.m_B = p1.m_B + p2.m_B;
return temp;
}
// 函数重载的版本
Person operator+(Person &p1,int num)
{
Person temp;
temp.m_A = p1.m_A + num;
temp.m_B = p1.m_B + num;
return temp;
}
void test()
{
Person p1;
p1.m_A = 10;
p1.m_B = 10;
Person p2;
p2.m_A = 10;
p2.m_B = 10;
Person p3 = p1 + p2;
cout<<"p3.m_A = "<<p3.m_A<<endl;
cout<<"p3.m_B = "<<p3.m_B<<endl;
Person p4 = p1 + 90;
cout<<"p4.m_A = "<<p4.m_A<<endl;
cout<<"p4.m_B = "<<p4.m_B<<endl;
}
int main()
{
test();
system("pause");
return 0;
};
运行结果:
p3.m_A = 20
p3.m_B = 20
p4.m_A = 100
p4.m_B = 100
请按任意键继续. . .
左移运算符重载
作用:可以输出自定义数据类型
#include <iostream>
using namespace std;
// 左移运算符重载
class Person
{
friend ostream &operator<<(ostream &cout,Person &p);
public:
Person(int a,int b)
{
m_A = a;
m_B = b;
}
private:
int m_A;
int m_B;
};
ostream &operator<<(ostream &cout,Person &p)
{
cout<<"m_A = "<<p.m_A<<" m_B = "<<p.m_B<<endl;
return cout;
}
void test()
{
Person p(10,10);
cout<<p<<endl;
cout<<p<<"Hello C++!"<<endl;
}
int main()
{
test();
system("pause");
return 0;
}
运行结果:
m_A = 10 m_B = 10
m_A = 10 m_B = 10
Hello C++!
请按任意键继续. . .
递增运算符重载
作用:通过重载递增运算符,实现自己的整型数据
#include <iostream>
using namespace std;
// 递增运算符重载
// 自定义整型
class MyInteger
{
friend ostream & operator<<(ostream & cout, MyInteger myint);
public:
MyInteger()
{
m_Num = 0;
}
// 重载前置++运算符
// 返回引用:为了一直对一个数据进行操作
MyInteger & operator++()
{
m_Num++;
return *this;
}
// 重载后置++运算符
// int 代表占位参数,用于区分前置和后置递增
MyInteger operator++(int)
{
// 先,记录当时结果
MyInteger temp = *this;
// 后,递增
m_Num++;
return temp;
}
private:
int m_Num;
};
// 重装左移运算符
ostream & operator<<(ostream & cout, MyInteger myint)
{
cout<<myint.m_Num;
return cout;
}
void test()
{
MyInteger myint;
cout<<myint<<endl;
cout<<++myint<<endl;
cout<<++(++myint)<<endl;
}
void test2()
{
MyInteger myint2;
cout<<myint2++<<endl;
cout<<myint2<<endl;
}
int main()
{
test();
cout<<endl;
test2();
system("pause");
return 0;
}
运行结果:
0
1
3
0
1
请按任意键继续. . .
赋值运算符重载
C++编译器至少给一个类添加4个函数
默认构造函数(无参,函数体为空)
默认析构函数(无参,函数体为空)
默认拷贝构造函数,对属性进行值拷贝
赋值运算符 operator=,对属性进行值拷贝
如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题
#include <iostream>
using namespace std;
// 赋值运算符重载
class Person
{
public:
Person(int age)
{
m_Age = new int(age);
}
~Person()
{
if(m_Age!=NULL)
{
delete m_Age;
m_Age = NULL;
}
}
// 重载赋值运算符
Person & operator=(Person &p)
{
// 编译器提供的是浅拷贝
// m_Age = p.m_Age;
if(m_Age!=NULL)
{
delete m_Age;
m_Age = NULL;
}
// 深拷贝
m_Age = new int(*p.m_Age);
return * this;
}
int *m_Age;
};
void test()
{
Person p1(11);
cout<<"p1的年龄为:"<<*p1.m_Age<<endl;
Person p2(21);
cout<<"p2的年龄为:"<<*p2.m_Age<<endl;
Person p3(31);
cout<<"p3的年龄为:"<<*p3.m_Age<<endl;
cout<<"-----------------------"<<endl;
p3 = p2 = p1;
cout<<"p1的年龄为:"<<*p1.m_Age<<endl;
cout<<"p2的年龄为:"<<*p2.m_Age<<endl;
cout<<"p3的年龄为:"<<*p3.m_Age<<endl;
}
int main()
{
test();
system("pause");
return 0;
}
运行结果:
p1的年龄为:11
p2的年龄为:21
p3的年龄为:31
-----------------------
p1的年龄为:11
p2的年龄为:11
p3的年龄为:11
请按任意键继续. . .
关系运算符重载
作用:重载关系运算符,可以让两个自定义类型对象进行对比操作
#include <iostream>
#include <string>
using namespace std;
// 关系运算符重载
class Person
{
public:
Person(string name, int age)
{
m_Name = name;
m_Age = age;
}
// 重载 == 号
bool operator==(Person &p)
{
if(this->m_Age==p.m_Age && this->m_Name==p.m_Name)
{
return true;
}
return false;
}
// 重载 != 号
bool operator!=(Person &p)
{
if(this->m_Age==p.m_Age && this->m_Name==p.m_Name)
{
return false;
}
return true;
}
string m_Name;
int m_Age;
};
void test()
{
Person p1("Tom", 11);
Person p2("Tom", 11);
if(p1==p2)
{
cout<<"p1和p2是相等的"<<endl;
}
else
{
cout<<"p1和p2是不相等的"<<endl;
}
if(p1!=p2)
{
cout<<"p1和p2是不相等的"<<endl;
}
else
{
cout<<"p1和p2是相等的"<<endl;
}
}
int main()
{
test();
system("pause");
return 0;
}
运行结果:
p1和p2是相等的
p1和p2是相等的
请按任意键继续. . .
函数调用运算符重载
函数调用运算符()也可以重载
由于重载后使用的方式非常像函数的调用,因此称为仿函数
仿函数没有固定写法,非常灵活
#include <iostream>
#include <string>
using namespace std;
// 函数调用运算符重载
class MyPrint
{
public:
// 重载打印输出
void operator()(string test)
{
cout<<test<<endl;
}
};
// 写一个打印输出的函数
void MyPrint02(string test)
{
cout<<test<<endl;
}
void test01()
{
MyPrint myPrint;
myPrint("Hello C++!"); // 重载调用;仿函数
MyPrint02("Hello C++!"); // 函数调用
}
// 加法类的仿函数
class MyAdd
{
public:
int operator()(int num1,int num2)
{
return num1+num2;
}
};
void test02()
{
MyAdd myadd;
int ret = myadd(100,100);
cout<<"ret = "<<ret<<endl;
// (调用)匿名函数对象:当前行执行完就立即被释放
cout<<MyAdd()(100,100)<<endl;
}
int main()
{
test01();
test02();
system("pause");
return 0;
}
运行结果:
Hello C++!
Hello C++!
ret = 200
200
请按任意键继续. . .