运算符重载

加号运算符

1.成员函数承载运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Person
{
public:

//成员函数重载运算符
Person operator+(Person& p)
{
Person t;
t.m_A = this->m_A + p.m_A;
t.m_B = this->m_B + p.m_B;

return t;
}


int m_A;
int m_B;
};
//成员函数重载+的本质:p3=p1.operator+(p2)

2.全局函数重载运算符

1
2
3
4
5
6
7
8
9
10
//全局函数重载加号
Person operator+(Person& p1, Person& p2)
{
Person t;
t.m_A = p1.m_A+ p2.m_A;
t.m_B = p1.m_B + p2.m_B;

return t;
}
//全局函数重载本质调用:p3=operator+(p1,p2)

ps:运算符重载也可以发生函数重载

1
2
3
4
5
6
7
8
9
10
11
void test01()
{
Person p1;
Person p2;
p1.m_A = 10;
p1.m_B = 10;
p2.m_A = 10;
p2.m_B = 10;

Person p3 = p1 + p2;
}

左移运算符重载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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;
};

//只能用全局函数重载左移运算符
//cout输出流对象只能有一个,所以要用引用的方式
ostream& operator<<(ostream &cout,Person &p)
{
cout << "m_A=" << p.m_A << "m_B=" << p.m_B;


return cout;
}

void test01()
{
Person p(10, 10);

cout << p << endl;
}

递增运算符重载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
class MyInteger
{
friend ostream& operator<<(ostream& cout, MyInteger myint);

public:
MyInteger()
{
m_Num = 0;
}

//重载++运算符 前置
//返回引用是为了一直对一个数据进行操作
MyInteger& operator++()
{
m_Num++;
return *this;
}

//重载++运算符 后置
//返回值 而不是引用
MyInteger operator++(int) //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 test01()
{
MyInteger myint;

cout << ++myint << endl;//输出1
}

void test02()
{
MyInteger myint;

cout << myint++ << endl;//输出0
cout << myint << endl;//输出1
}

赋值运算符重载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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)
{
//先判断是否有属性在堆区,如果有先释放干净,再进行深拷贝
if (m_Age != NULL)
{
delete m_Age;
m_Age = NULL;
}
//深拷贝
m_Age = new int(*p.m_Age);
return *this;
//this是一个指向当前对象的指针,类型为Person*
//*this表示当前对象本身(而不是指针)
}

int* m_Age;
};

void test01()
{
Person p1(18);
Person p2(20);
Person p3(30);

p3 = p2 = p1;//因为重载时的返回类型是对象的引用,所以可以连续运算

cout << "p1的年龄" << *p1.m_Age;
cout << "p1的年龄" << *p2.m_Age;
}

关系运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Person
{
public:
Person(string name, int age)
{
m_Name = name;
m_Age = age;
}

bool operator==(Person& p)
{
if (this->m_Name == p.m_Name && this->m_Age == p.m_Age)
{
return true;
}

return false;
}

string m_Name;
int m_Age;
};

函数调用运算符重载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class MyPrint
{
public:

void operator()(string test)
{
cout << test << endl;
}
};

void test01()
{
MyPrint myPrint;
myPrint("hello world");//执行这条语句 会有输出:hello world
//由于使用起来非常类似于函数调用,因此称为仿函数
}

//仿函数非常灵活,没有固定写法
//加法类
class MyAdd
{
public:
int operator()(int num1, int num2)
{
return num1 + num2;
}
};

void test02()
{
MyAdd myadd;
int ret = myadd(100, 100);

//匿名对象的调用 类名()
cout << MyAdd()(100, 100) << endl;
}