(1)加法运算符重载:
#include <iostream>
#include <cstring>
using namespace std;
//运算符重载
//对于内置数据类型,编译器已经预置好
// 1.成员函数实现重载
class Person
{
public:
/*
//本质 Person p3 = p1.operator+(p2)
Person operator+(Person &p)
{
this->m_A += this->m_A + p.m_A;
this->m_B += this->m_B + p.m_B;
return *this;
}
*/
int m_A;
int m_B;
};
// 2.全局函数重载+号 Person p3 = operator+(p1,p2)
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 test01()
{
Person p1;
p1.m_A = 10;
p1.m_B = 10;
Person p2;
p2.m_A = 10;
p2.m_B = 10;
Person p3 = p1 + p2;
p3 = p2+100;
cout << "p3.m_A="<<p3.m_A<<endl;
cout << "p3.m_B="<<p3.m_B<<endl;
}
int main()
{
test01();
return 0;
}
(2)左移运算符的重载也有两种
1.成员函数
ostream& operator<<(ostream &cout)
{
cout << "m_A = "<<this->m_A<<" m_B = "<<this->m_B;
return cout;
}
//调用:p<<cout<<"hello"<<endl;
但如果实现cout<<p<<endl;这种形式必须使用
2.全局函数实现重载 完整代码如下:
需要强调的是cout为C++内置ostream 对象 是唯一的 返回的时候要用引用的格式 因为值传递会有一个复制的过程
#include <iostream>
#include <cstring>
using namespace std;
class Person
{
public:
int m_A;
int m_B;
};
ostream& operator<<(ostream &cout,Person &p) //本质 operator<< (cout, p)简化为cout << p
{
cout << "m_A = "<<p.m_A<<" m_B = "<<p.m_B;
return cout;
}
void test01()
{
Person p;
p.m_A = 10;
p.m_B = 10;
cout<<p<<"hello"<<endl;
}
int main()
{
test01();
return 0;
}
3.递增运算符重载
递增有前置后置之分
对于前置 可返回引用
因为主要是使用this指针做递增
而对于后置 只可返回值 因为内部涉及局部变量 而局部变量不可返回引用。
除此之外
1、代码里涉及到了重载<<运算符 需要注意应当使用值传递 而不能用引用 原因是因为后置递增
2.前置后置函数重载不可依靠返回值不同实现 编译器内置了使用(int)占位符进行区分
#include <iostream>
#include <cstring>
using namespace std;
//递增运算符重载
//自定义整型
class MyInteger
{
friend ostream& operator<<(ostream& cout, MyInteger myint);
public:
MyInteger()
{
m_Num = 0;
}
//重载前置++运算符
MyInteger& operator++()
{
++this->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 test02()
{
MyInteger myint;
cout << myint++<<endl;
cout << myint <<endl;
cout << ++myint <<endl;
}
int main()
{
test02();
return 0;
}
则递减运算符如下所示:
#include <iostream>
#include <cstring>
using namespace std;
//递增运算符重载
//自定义整型
class MyInteger
{
friend ostream& operator<<(ostream& cout, MyInteger myint);
public:
MyInteger()
{
m_Num = 0;
}
//重载前置++运算符
MyInteger& operator--()
{
--this->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 test02()
{
MyInteger myint;
cout << myint--<<endl;
cout << myint <<endl;
cout << --myint <<endl;
}
int main()
{
//test01();
test02();
return 0;
}
4.赋值运算符重载
C++编译器默认给类提供了赋值预算符 不过只能进行值拷贝 与默认拷贝构造函数类似 其容易造成浅拷贝现象,当涉及到堆区内存时(new)时 需要重构。
重构的原则是应当先判断是否有属性在堆区,如果有先释放干净 在深拷贝,注意链式原则。
Person& operator=(Person &p)
{
//应该先判断是否有属性在堆区,如果有先释放干净 在深拷贝
if(m_age != NULL)
{
delete m_age;
m_age = NULL;
}
m_age = new int(*p.m_age);
return *this;
}
完整demo
#include <iostream>
#include <cstring>
using namespace std;
//赋值运算符重载
class Person
{
friend void test01();
public:
Person(int age)
{
m_age = new int (age);
}
Person& operator=(Person &p)
{
//应该先判断是否有属性在堆区,如果有先释放干净 在深拷贝
if(m_age != NULL)
{
delete m_age;
m_age = NULL;
}
m_age = new int(*p.m_age);
return *this;
}
~Person()
{
if(m_age != NULL)
{
delete m_age;
m_age = NULL;
}
}
private:
int *m_age;
};
void test01()
{
Person p1(18);
Person p2(20); //浅拷贝 当释放时容易崩溃
Person p3 = p2 = p1;
cout << "p1.age:"<<*p1.m_age<<endl;
cout << "p2.age:"<<*p2.m_age<<endl;
cout << "p3.age:"<<*p3.m_age<<endl;
}
int main()
{
test01();
return 0;
}
4.关系运算符
#include <iostream>
#include <cstring>
using namespace std;
//赋值运算符重载
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;
else
return false;
}
string m_Name;
int m_Age;
};
void test01()
{
Person p1("Tom", 18);
Person p2("Tom1", 18);
if (p1 == p2)
{
cout <<"p1 == p2\n";
}
else
{
cout <<"p1 != p2\n";
}
}
int main()
{
test01();
return 0;
}
5.仿函数 对()的重载
void operator()(string test)
{
cout<<test<<endl;
}
//匿名对象也可以使用仿函数
Myprint()("hello");