重载加减运算符
成员函数进行运算符重载
{
this->m_A = a;
this->m_B = b;
}
//成员函数实现 + 号运算符重载
Person operator+(const Person& p) {
Person temp;
temp.m_A = this->m_A + p.m_A;
temp.m_B = this->m_B + p.m_B;
return temp;
}
public:
int m_A;
int m_B;
};
//全局函数实现 + 号运算符重载
//Person operator+(const Person& p1, const Person& p2) {
// Person temp(0, 0);
// temp.m_A = p1.m_A + p2.m_A;
// temp.m_B = p1.m_B + p2.m_B;
// return temp;
//}
//运算符重载 可以发生函数重载
Person operator+(const Person& p2, int val)
{
Person temp;
temp.m_A = p2.m_A + val;
temp.m_B = p2.m_B + val;
return temp;
}
void test() {
Person p1(10, 10);
Person p2(20, 20);
//成员函数方式
Person p3 = p2 + p1; //相当于 p2.operaor+(p1)
cout << "mA:" << p3.m_A << " mB:" << p3.m_B << endl;
Person p4 = p3 + 10; //相当于 operator+(p3,10)
cout << "mA:" << p4.m_A << " mB:" << p4.m_B << endl;
}
int main() {
test();
system("pause");
return 0;
}
总结1:对于内置的数据类型的表达式的的运算符是不可能改变的 总结2:不要滥用运算符重载
未使用重载进行计算
class Person {
public:
Person(int v1, int v2) {
m_v1 = v1;
m_v2 = v2;
}
int m_v1;
int m_v2;
Person add(Person& p) {
Person temp;
temp.m_v1 = this->m_v1 + p.m_v1;
temp.m_v2 = this->m_v2 + p.m_v2;
return temp;
}
};
void Example() {
Person p1(10,20);
Person p2(30,40);
p2 = p2.add(p1);
cout << "P2.M_V1 = " << p2.m_v1 << endl;
cout << "P2.M_V2 =" << p2.m_v2 << endl;
}//实际上是一个浅拷贝
使用重载运算符
#include <iostream>
#include <cstdio>
#include <malloc.h>
using namespace std;
class Person {
public:
Person():m_v1(0),m_v2(0) {}
Person(int v1, int v2) {
m_v1 = v1;
m_v2 = v2;
}
int m_v1;
int m_v2;
Person operator+ (Person& p) {
Person temp;
temp.m_v1 = this->m_v1 + p.m_v1;
temp.m_v2 = this->m_v2 + p.m_v2;
return temp;
}
};
void Example() {
Person p1(10,20);
Person p2(30,40);
Person p3= p2 + p1;
cout << "P2.M_V1 = " << p3.m_v1 << endl;
cout << "P2.M_V2 =" << p3.m_v2 << endl;
}
int main() {
Example();
return 0;
}
全局重载需要两个引用
#include <iostream>
#include <cstdio>
#include <malloc.h>
using namespace std;
class Person {
public:
Person():m_v1(0),m_v2(0) {}
Person(int v1, int v2) {
m_v1 = v1;
m_v2 = v2;
}
int m_v1;
int m_v2;
};
Person operator+(Person& p1, Person& p2) {
Person temp;
temp.m_v1 = p1.m_v1 + p2.m_v1;
temp.m_v2 = p1.m_v2 + p2.m_v2;
return temp;
}
void Example() {
Person p1(10,20);
Person p2(30,40);
Person p3= p2 + p1;
cout << "P2.M_V1 = " << p3.m_v1 << endl;
cout << "P2.M_V2 =" << p3.m_v2 << endl;
}
int main() {
Example();
return 0;
}
重载左移运算符
一般来说不使用成员函数来重载左移运算符,因为cout在左移运算符的左边,如果重载,对象只能在右边。
所以使用全局函数来重载左移运算符。
class Person {
public:
Person(int a,int b) {
this->m_a = a;
this->m_b = b;
}
int m_a;
int m_b;
};
void operator<<(ostream& cout, Person& p) {
cout << "m_a = " << p.m_a << " m_b = " << p.m_b;
}
void Example() {
Person p(1, 2);
cout << p;
}
全局函数重载可解决问题,但是返回值是void,后面无法加入endl;
返回值改为原有的对象,也就是cout,就可以解决问题,加入return cout
ostream& operator<<(ostream& cout, Person& p) {
cout << "m_a = " << p.m_a << " m_b = " << p.m_b;
return cout;
}
void Example() {
Person p(1, 2);
cout << p << endl;
}
问题即可解决。
在实际编程规范中,成员变量一般为私有的,那全局重载就需要将全局函数变为友元
class Person {
friend ostream& operator<<(ostream& cout, Person& p);
public:
Person(int a,int b) {
this->m_a = a;
this->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;
return cout;
}
总结:重载左移运算符配合友元可以实现输出自定义数据类型
重载自增运算符
前置自增
class myInt {
friend ostream& operator<<(ostream& cout, myInt& in);
public:
myInt() {
m_int = 0;
}
//返回引用是为了一直对同一个对象进行递增,否则将会返回新的对象
myInt& operator++() {
m_int++;
return *this;
}
private:
int m_int;
};
ostream& operator<<(ostream& cout, myInt& in) {
cout << in.m_int;
return cout;
}
void Example() {
myInt myint;
cout << myint << endl;
}
后置自增
void operator++(int) {
//int 是一个占位参数,可以用于区分前置运算符和后置运算符
//先记录初始结果
//再进行递增运算
//然后再返回最后结果
}
myInt operator++(int) {
//int 是一个占位参数,可以用于区分前置运算符和后置运算符
myInt temp;
temp = *this;
this->m_int++;
return temp;
}
class MyInteger {
friend ostream& operator<<(ostream& out, MyInteger myint);
public:
MyInteger() {
m_Num = 0;
}
//前置++
MyInteger& operator++() {
//先++
m_Num++;
//再返回
return *this;
}
//后置++
MyInteger operator++(int) {
//先返回
MyInteger temp = *this; //记录当前本身的值,然后让本身的值加1,但是返回的是以前的值,达到先返回后++;
m_Num++;
return temp;
}
private:
int m_Num;
};
ostream& operator<<(ostream& out, MyInteger myint) {
out << myint.m_Num;
return out;
}
//前置++ 先++ 再返回
void test01() {
MyInteger myInt;
cout << ++myInt << endl;
cout << myInt << endl;
}
//后置++ 先返回 再++
void test02() {
MyInteger myInt;
cout << myInt++ << endl;
cout << myInt << endl;
}
int main() {
test01();
//test02();
system("pause");
return 0;
}
重载赋值运算符
再深浅拷贝中提到的下列问题可通过自己设计深拷贝解决:
class Person {
public:
Person(int a) {
m_age = new int(a);
}
~Person() {
if (m_age != NULL) {
delete m_age;
}
}
Person(const Person& p) {
m_age = new int(*p.m_age);
}
int *m_age;
};
void example() {
Person p1(18);
Person p2(p1);
cout << *p2.m_age << endl;
}
但若表达式为赋值而非传参,则需要对赋值运算符进行重载
#include <iostream>
#include <string>
using namespace std;
class Person {
public:
Person(int a) {
m_age = new int(a);
}
~Person() {
if (m_age != NULL) {
delete m_age;
}
}
Person& operator=(Person &p) {
//如果堆区存在数据,则需要先进行delete清理
if (this->m_age != NULL) {
delete m_age;
}
this->m_age = new int(*p.m_age);
//然后再进行深拷贝
//要想连等成功,必须要返回一个对象
//左值右值的类型相同
return *this;
//返回自身可以实现类型相同
//this类型是Person引用
}
//Person(const Person& p) {
// m_age = new int(*p.m_age);
//}
int *m_age;
};
void example() {
Person p1(18);
Person p2(20);
Person p3(30);
p1 = p2 = p3;
cout << *p1.m_age << endl;
cout << *p2.m_age << endl;
cout << *p3.m_age << endl;
}
int main() {
example();
return 0;
}
重载关系运算符
#include <iostream>
#include <string>
using namespace std;
class Person {
public:
Person(string str,int age) {
this->age = age;
name = str;
}
bool operator==(const Person& p) {
if (p.age == this->age && this->name == p.name) {
return true;
}
else return false;
}
bool operator!=(const Person& p) {
if(p.age != this->age || this->name != p.name) {
return true;
}
else return false;
}
string name;
int age;
};
void example() {
Person p1("zhang", 18);
Person p2("zhang", 18);
Person p3("li", 20);
if (p1 != p3) {
cout << "Reconstruct Complete";
}
}
int main() {
example();
return 0;
}
重载函数调用运算符
仿函数
#include <iostream>
#include <string>
using namespace std;
class Person {
public:
void operator()(string str) {
cout << str << endl;
}
};
void example() {
Person print;
print("Hello World!");
//由于使用起来非常像函数,所以称为仿函数
}
int main() {
example();
return 0;
}
仿函数非常灵活,不限于写法