在完成对C语言的学习后,我最近开始了对C++和Java的学习,目前跟着视频学习了一些语法,也跟着敲了一些代码,有了一定的掌握程度。现在将跟着视频做的笔记进行整理。本篇博客是整理C++知识点的第十四篇博客。
本篇博客介绍了C++的运算符重载。
本系列博客所有C++代码都在Visual Studio 2022环境下编译运行。程序为64位。
目录
运算符重载是对已有的运算符重新进行定义,赋予另一种功能,以适应不同的数据类型。
加号运算符重载可以实现两个自定义数据类型相加。
运算符重载分为全局函数重载和成员函数重载。
对于内置的数据类型的表达式,其运算符是不能改变的。
不要滥用运算符重载。
- #include
- using namespace std;
- class person {
- public:
- int A;
- int B;
- void show() {
- cout << "A = " << A << endl;
- cout << "B = " << B << endl;
- }
-
- person operator+(person &p) {
- person temp;
- temp.A = this->A + p.A;
- temp.B = this->B + p.B;
- return temp;
- }
- };
-
- int main(void)
- {
- person a, b;
- a.A = 10;
- a.B = 10;
- b.A = 15;
- b.B = 15;
- person c = a + b;
- c.show();
- return 0;
- }
person类有成员变量A和B,show函数输出A和B的值。person类重载了运算符+,重载后接受一个person类对象的引用作为参数,重载后的运算符创建一个person类,将这个类与本类的A和B的值分别相加,结果赋给person类对应成员,随后返回此类。
main函数创建了person类对象a和b,其成员变量A的值均为10,成员变量B的值均为15。将两个类相加后赋给类对象c。
程序的输出是:
A = 25
B = 25
- #include
- using namespace std;
- class person {
- public:
- int A;
- int B;
- void show() {
- cout << "A = " << A << endl;
- cout << "B = " << B << endl;
- }
- };
-
- person operator+ (person& a, person& b) {
- person temp;
- temp.A = a.A + b.A;
- temp.B = a.B + b.B;
- return temp;
- }
- int main(void)
- {
- person a, b;
- a.A = 10;
- a.B = 10;
- b.A = 15;
- b.B = 15;
- person c = a + b;
- c.show();
- return 0;
- }
这段代码的person类设计和上面基本一样。但是本段代码将+的重载放在类外,接受两个person类对象,并创建临时类对象,将对应成员相加后赋给此对象对应变量,最后返回此对象。
程序的输出是:
A = 25
B = 25
不用成员函数重载左移运算符,因为无法实现cout在左侧。cout是ostream类的对象。
- #include
- using namespace std;
- class test {
- public:
- int A;
- int B;
- };
-
- void operator<< (ostream& cout, test& temp) {
- cout << "A = " << temp.A << endl;
- cout << "B = " << temp.B << endl;
- }
- int main(void) {
- test temp;
- temp.A = 10;
- temp.B = 15;
- cout << temp;
- return 0;
- }
程序提供了test类,test类有成员变量A和B。程序重载了<<运算符,接受cout的引用,和一个test类对象,并输出此类对象的A和B成员值。
main函数创建了一个test类对象,并使用了重载后的<<。
程序的输出是:
A = 10
B = 15
递增运算符有前置和后置,使用占位参数区分前置和后置递增。
- #include
- using namespace std;
- class test {
- public:
- int number;
- test operator++() {
- this->number += 1;
- return *this;
- }
- };
- int main(void)
- {
- test temp;
- temp.number = 10;
- temp = ++temp;
- cout << "number = " << temp.number << endl;
- return 0;
- }
程序创建了一个test类,有成员变量number,类内重载了前置的++,重载后将本类的number加一后返回本身。main函数测试了前置++的重载。
程序的输出是:
number = 11
- #include
- using namespace std;
- class test {
- public:
- int number;
- test operator++(int) {
- test temp;
- temp.number = this->number;
- this->number += 1;
- return temp;
- }
- };
-
- int main(void)
- {
- test temp;
- temp.number = 10;
- cout << "number = " << temp.number++ << endl;
- cout << "number = " << temp.number << endl;
- return 0;
- }
程序创建了一个test类,test类有成员变量number,并重载了后置++。重载后置++时,首先创建一个test类对象temp,随后将本类成员变量number的值赋给temp的number,随后将本类的number+1,返回temp类对象。重载后置++使用了占位参数。
main函数创建test类对象temp,将temp的number赋值为10,随后执行后置++,输出结果的number的值,然后再输出temp的number。
程序的输出是:
number = 10
number = 11
C++编译器至少给一个类添加四个函数,无参且函数体为空的默认构造函数,无参且函数体为空的析构函数,默认拷贝构造函数(对属性进行值拷贝),赋值运算符=,对属性进行值拷贝。
如果类中有属性指向堆区,使用=时也要注意深浅拷贝问题,默认为浅拷贝。
- #include
- using namespace std;
- class test {
- public:
- int* number = new int();
- test& operator=(test &temp) {
- if (number != NULL) {
- delete number;
- number = NULL;
- }
- this->number = new int(*temp.number);
- return *this;
- }
- ~test() {
- delete number;
- }
- };
- int main(void)
- {
- test t1, t2;
- *(t1.number) = 10;
- cout << *(t1.number) << endl;
- t2 = t1;
- cout << *(t2.number) << endl;
- return 0;
- }
程序中test类的成员number的内存开辟在堆区,在重载操作符=时,首先如果number的地址不为空就释放后置空,然后开辟空间,将要拷贝的值放在新空间,再将本类引用后返回。析构函数销毁number。
main函数创建了test类的两个对象t1和t2,并使用了一次=。程序的输出是:
10
10
- #include
- #include
- using namespace std;
- class test {
- public:
- string name;
- int age;
-
- bool operator==(test &temp) {
- if (this->age == temp.age && this->name == temp.name) {
- return true;
- }
- else {
- return false;
- }
- }
- };
-
- int main(void)
- {
- test t1, t2;
- t1.name = "Tom";
- t1.age = 20;
- t2.name = "Jerry";
- t2.age = 27;
-
- if (t1 == t2) {
- cout << "true" << endl;
- }
- else {
- cout << "false" << endl;
- }
- return 0;
- }
程序创建了test类,有成员变量name和age。重载==进行两个类对象的比较,只有成员name和age都相等时判定相等,否则判定不相等。main函数进行了测试。程序的输出是:
false
函数调用运算符()也可以重载,重载后使用方式像函数调用,也称为仿函数。仿函数没有固定写法,比较灵活。
- #include
- #include
- using namespace std;
- class test {
- public:
- void operator() (string name){
- cout << name << endl;
- }
- };
- int main(void)
- {
- test temp;
- temp("Hello C++");
- return 0;
- }
程序的test类重载了(),仿函数有一个参数name,并输出name的内容。main函数创建了一个test类对象temp,并调用仿函数。程序的输出是:
Hello C++
- #include
- using namespace std;
- class test {
- public:
- int operator() (int a, int b) {
- return a + b;
- }
- };
-
- int main(void)
- {
- test temp;
- cout << temp(10, 5) << endl;
- cout << test()(3, 4) << endl;
- return 0;
- }
程序的test类重载了(),重载后接受两个参数,并返回和。main函数分别用类对象和匿名对象调用仿函数。程序的输出是:
15
7