运算符重载
● 概念:对于已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型
加号运算符重载
● 作用:实现两个自定义数据类型相加的运算
//
// Created by NJUST'er'wang's on 2022/1/15.
//加号“+”运算符重载
#include <iostream>
#include <string>
using namespace std;
class Student {
string name;
float score;
float sumScore;
public:
void setName(string name) { this->name = name; }
void setScore(float score) { this->score = score; }
string getName() { return name; }
float getScore() { return score; }
float getSumScore() { return sumScore; }
//成员函数重载“+”
// Student operator+(Student &stu) {
// Student s_temp;
// s_temp.score = this->score + stu.score;
// return s_temp;
// }
};
//全局函数重载
Student operator+(Student &student1,Student &student2){
Student s_temp;
s_temp.setScore(student1.getScore() + student2.getScore());
return s_temp;
}
void test01() {
Student s1;
s1.setScore(80);
Student s2;
s2.setScore(78);
Student s3 = s1 + s2;
cout << "Student s3's score is: " << s3.getScore() << endl;
}
void test02(){
Student s1;
s1.setScore(91);
Student s2;
s2.setScore(78);
Student s3 = s1 + s2;
cout << "Student s3's score is: " << s3.getScore() << endl;
}
int main() {
// test01();
test02();
return 0;
}
/*
Student s3's score is: 169
*/
● 注意:
○ 对于内置的数据类型的表达式的运算符是不可能改变的;
○ 不要滥用运算符重载
左移运算符重载
//
// Created by NJUST'er'wang's on 2022/1/15.
//左移运算符重载
#include <iostream>
using namespace std;
class Test{
int ID;
public:
void setID(int ID) { this->ID = ID; }
int getID() { return ID; }
/* 成员函数返回重载运算符
* 通常不会使用成员函数重载左移运算符
* 因为不能实现cout在左侧
* */
};
//全局函数重载左移运算符
ostream &operator<<(ostream &cout,Test &test){
cout<<"The ID in Test is: "<<test.getID();
return cout; //此处为了是"<<"运算符能链式编程
}
void test01(){
Test test;
test.setID(01);
// cout<<test.getID()<<endl;
cout<<test<<endl;
}
int main()
{
test01();
return 0;
}
/*
The ID in Test is: 1
*/
递增运算符重载
//
// Created by NJUST'er'wang's on 2022/1/17.
//递增运算符重载
#include <iostream>
using namespace std;
class MyInteger {
int num;
public:
MyInteger() { num = 0; }
void setNum(int num) { this->num = num; }
int getNum() { return num; }
/* 重载 ++ 运算符 */
//前置++
MyInteger &operator++() { //返回引用是为了能够一直对一个数据进行自增操作
this->num++;
return *this;
}
//后置++
MyInteger operator++(int) {//int代表占位参数,用以区分前置和后置++
//记录结果
MyInteger tmp = *this;
//本身++
this->num++;
//返回记录的值
return tmp;
}
};
//重载左移(<<)运算符
ostream &operator<<(ostream &cout, MyInteger m) {
cout << "The num is: " << m.getNum() << endl;
return cout;
}
void test01() {
MyInteger myInteger;
cout << "前置++:" << ++myInteger;
}
void test02() {
MyInteger m;
cout << "后置++:" << m++ << endl;
cout << "m++后:" << m << endl;
}
int main() {
test01();
test02();
return 0;
}
/*
前置++:The num is: 1
后置++:The num is: 0
m++后:The num is: 1
*/
赋值运算符重载
● C++编译器至少给一个类添加四个函数
○ 默认构造函数(无参)
○ 默认析构函数(无参)
○ 默认拷贝构造函数,对属性值进行拷贝
○ 赋值运算符 operator= ,对属性进行值拷贝
● 如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题
//
// Created by NJUST'er'wang's on 2022/1/18.
//赋值运算符重载
#include <iostream>
using namespace std;
class Person {
int *age;
public:
Person(int age) { this->age = new int(age); }
~Person() {
if (age != NULL) {
delete age;
age = NULL;
}
}
//重载赋值运算符
Person &operator=(Person &person) {
//编译器提供的是浅拷贝
//this->age = person.age;
//应该先判断是否有属性在堆区,如果有先释放干净,然后再深拷贝
if (this->age != NULL) {
delete this->age;
this->age = NULL;
}
//深拷贝
this->age = new int(*person.age);
return *this;
}
int *getAge() { return age; }
};
void test01() {
Person p1(18);
Person p2(20);
Person p3(30);
p3 = p2 = p1;
cout << "p1的年龄为:" << *p1.getAge() << endl;
cout << "p2的年龄为:" << *p2.getAge() << endl;
cout << "p3的年龄为:" << *p3.getAge() << endl;
}
int main() {
test01();
return 0;
}
/*
p1的年龄为:18
p2的年龄为:18
p3的年龄为:18
*/
关系运算符重载
//
// Created by NJUST'er'wang's on 2022/1/18.
//关系运算符重载
#include <iostream>
#include <string>
using namespace std;
class Person {
string name;
int age;
public:
Person(string name, int age) {
this->name = name;
this->age = age;
}
string getName() { return name; }
int getAge() { return age; }
//重载比较运算符
bool operator==(Person &person) {
if (this->name == person.getName() && this->age == person.getAge()) {
return true;
}
return false;
}
};
void test01() {
Person p1("Whb", 7);
Person p2("Gxy", 7);
bool flag = (p1 == p2);
if (flag) {
cout << "p1和p2相等" << endl;
} else {
cout << "p1和p2不相等" << endl;
}
}
int main() {
test01();
return 0;
}
/*
p1和p2不相等
*/
函数调用运算符重载
● 函数调用运算符()
可以重载;
● 由于重载后使用的方式非常像函数的调用,因此称为仿函数;
● 仿函数没有固定写法,非常灵活
//
// Created by NJUST'er'wang's on 2022/1/18.
//函数重载运算符
#include <iostream>
#include <string>
using namespace std;
class MyPrint {
public:
//重载函数调用运算符
void operator()(string test) {
cout << test << endl;
}
};
void myPrint2(string test) {
cout << test << endl;
}
void test01() {
MyPrint myPrint;
cout << "运算符重载:" << endl;
myPrint("Hello World!");
/* 函数调用运算符
* 由于使用起来非常像函数调用,因此称其为仿函数
* 仿函数非常灵活,没有固定的写法
* 匿名函数对象
* */
cout << "函数调用:" << endl;
myPrint2("Hello World!");
}
int main() {
test01();
return 0;
}
/*
运算符重载:
Hello World!
函数调用:
Hello World!
*/